home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr09 / hac11.zip / HAC.PAS < prev    next >
Pascal/Delphi Source File  |  1993-06-23  |  93KB  |  2,293 lines

  1. (*
  2.     Home Accounts System
  3.     Version 1.1, June 1993
  4.     Copyright (C) 1992, 1993  Paul Coxwell.  All rights reserved.
  5. *)
  6.  
  7. PROGRAM HAC;
  8.  
  9. {$V-}
  10.  
  11. USES DOS,CRTCLERR,STRINGS,TIME,CRT,ENHCON;
  12.  
  13. CONST
  14.  
  15.     FNEXT       = '.DAT';       { EXTENSION FOR DATA FILES }
  16.     ACSTATFN    = 'ACSTAT';     { NAME OF ACCOUNT STATUS FILE }
  17.     TRANSFN     = 'TRANS';      { PREFIX FOR TRANSACTION FILE NAMES }
  18.     AUTOFN      = 'AUTO';       { PREFIX FOR AUTO TRANSACTIONS FILE NAMES }
  19.     HELPFN      = 'HAC.HLP';    { NAME OF ON-LINE HELP FILE }
  20.  
  21.     ACNAMELEN   = 30;           { MAX. LENGTH FOR ACCOUNT NAME }
  22.     DETAILLEN   = 20;           { MAX. LENGTH OF TRANSACTION DETAIL }
  23.  
  24.     MAXMONEY    = 999999999;    { MAX. VALUE OF $9,999,999.99 }
  25.     MNYFORMAT   = 'BCP14:2';    { FORMAT FOR DISPLAY OF AMOUNT, BLANK ZERO }
  26.     MNYZFORMAT  = 'CP14:2';     { FORMAT FOR DISPLAY OF AMOUNT, SHOW ZERO }
  27.     MNYDFORMAT  = '$CP14:2';    { FORMAT FOR DISPLAY OF AMOUNT, WITH SIGN }
  28.     MNYLFORMAT  = 'BLCP14:2';   { FORMAT FOR LEFT-JUSTIFIED MONEY EDITS }
  29.     MNYLZFORMAT = 'LCP14:2';    { FORMAT FOR LEFT-JUSTIFIED EDIT WITH ZERO }
  30.     MAXCHECKNUM = 999999;       { MAX. NUMBER FOR A CHECK }
  31.     CHKFORMAT   = 'Z6';         { FORMAT FOR CHECK NUMBERS }
  32.  
  33.     TRANSKEYS   = [CR,KEYUP,KEYDOWN,HT,KEYSTAB,KEYF10];
  34.     AUTOKEYS    = TRANSKEYS+[KEYPGUP,KEYPGDN,KEYCPGUP,KEYCPGDN,KEYF4];
  35.  
  36.     HELPONLINE: BOOLEAN = TRUE;         { SET IF HELP AVAILABLE }
  37.  
  38.     STATCOLOR:  BYTE = MONONORMAL;      { COLOR OF STATUS BLOCK }
  39.     TITLECOLOR: BYTE = MONOREVERSE;     { COLOR OF TITLES/HEADINGS }
  40.     MAINCOLOR:  BYTE = MONONORMAL;      { COLOR OF MAIN SCREEN AREA }
  41.     HIGHCOLOR:  BYTE = MONOINTENSE;     { COLOR OF HIGHLIGHTED TEXT }
  42.  
  43.  
  44. TYPE
  45.  
  46.     ACCOUNTTYPE = (UNUSED,CHECKING,SAVINGS,CARD);
  47.  
  48.     ACCOUNTREC  =   RECORD
  49.                         NAME:       STRING[ACNAMELEN];  { ACCOUNT NAME }
  50.                         ACTYPE:     ACCOUNTTYPE;        { TYPE OF ACCOUNT }
  51.                         RECBAL,                         { TOTAL RECONCILED }
  52.                         UNRECBAL,                       { TOTAL UNRECONCILED }
  53.                         CHECKNUM:   LONGINT;            { NEXT CHECK NUMBER }
  54.                         DRDEFAULT,                      { MISC. DEBIT TEXT }
  55.                         CRDEFAULT:  STRING[DETAILLEN];  { MISC. CREDIT TEXT }
  56.                     END;
  57.  
  58.     TRANSTYPE   = (USER,AUTO,XFER);
  59.     RECONTYPE   = (UNREC,REC,BAL);
  60.     AUTOTYPE    = (DEBIT,CREDIT);
  61.  
  62.     TRANSREC    =   RECORD
  63.                         DATE:       WORD;               { TRANSACTION DATE }
  64.                         AMOUNT,                         { AMOUNT IN CENTS }
  65.                         BALANCE:    LONGINT;            { BALANCE TO DATE }
  66.                         DETAIL:     STRING[DETAILLEN];  { DESCRIPTION }
  67.                         RECON:      RECONTYPE;          { RECONCILIATION FLAG }
  68.                     END;
  69.  
  70.     AUTOREC     =   RECORD
  71.                         DATE:       DATEREC;            { DATE OF NEXT ENTRY }
  72.                         UPDATE:     LONGINT;            { UPDATE PERIOD }
  73.                         COUNT:      LONGINT;            { NUMBER OF ENTRIES }
  74.                         AUTODRCR:   AUTOTYPE;           { TRANSACTION TYPE }
  75.                         AMOUNT:     LONGINT;            { VALUE OF ENTRY }
  76.                         DETAIL:     STRING[DETAILLEN];  { DESCRIPTION }
  77.                     END;
  78.  
  79.  
  80.     PROMPTSTR   = STRING[38];       { STRING FOR YES/NO POP-UP WINDOW }
  81.  
  82.  
  83. VAR
  84.  
  85.     PRN:        TEXT;                           { PRINT OUTPUT }
  86.     ACSTATFILE: FILE OF ACCOUNTREC;             { ACCOUNT STATUS FILE }
  87.     TRANSFILE:  FILE OF TRANSREC;               { TRANSACTION FILES }
  88.     AUTOFILE:   FILE OF AUTOREC;                { AUTO ENTRY FILES }
  89.  
  90.     ACSTATUS:   ARRAY['A'..'Z'] OF ACCOUNTREC;  { STATUS OF ACCOUNT }
  91.  
  92.     STATWINDOW,                         { TOP STATUS BLOCK }
  93.     MAINWINDOW,                         { MAIN DISPLAY AREA }
  94.     PROMPTWINDOW,                       { POP-UP WINDOW FOR PROMPTS }
  95.     EDITERRWINDOW,                      { POP-UP WINDOW FOR ERROR MESSAGES }
  96.     CRTCLWINDOW,                        { POP-UP WINDOW FOR CRITICAL ERRORS }
  97.     VIEWWINDOW,                         { AREA FOR TRANSACTION DISPLAY }
  98.     ENTERWINDOW,                        { WINDOW FOR TRANSACTION ENTRY }
  99.     HELPSTATWINDOW,                     { HELP SYSTEM STATUS WINDOW }
  100.     OPTLINEWINDOW:  WINDOWDEFINITION;   { BOTTOM LINE MESSAGES }
  101.  
  102.     MONEYEDIT,                          { AMOUNT FIELDS FOR TRANS. ENTRY }
  103.     ACTYPEEDIT,                         { ACCOUNT TYPE IN SET-UP ROUTINE }
  104.     ACNAMEEDIT,                         { ACCOUNT NAME AND DETAIL }
  105.     ACREFEDIT,                          { AUX. ACCOUNT REFERENCE FIELD }
  106.     CHECKNUMEDIT,                       { CHECK NUMBERS }
  107.     TRANSDATEEDIT,                      { DATE }
  108.     APMONEYEDIT,                        { AMOUNT EDITING DURING AUTO PROCESS }
  109.     AUTODETAILEDIT,                     { DETAIL FOR AUTO ENTRIES }
  110.     AUTOMONEYEDIT,                      { AMOUNT FOR AUTO ENTRIES }
  111.     AUTODATEEDIT,                       { DATE FOR AUTO ENTRIES }
  112.     AUTONUMEDIT,                        { COUNT/INTERVAL FOR AUTO ENTRIES }
  113.     AUTOINTERVALEDIT: EDITFORMATREC;    { DAYS/MONTHS FIELD FOR AUTO ENTRIES }
  114.  
  115.     ONLINEHELP:     HELPCONFIGURATION;  { SETTINGS FOR HELP SYSTEM }
  116.  
  117.     MAINOPT:        CHAR;               { MAIN MENU OPTION }
  118.     CONFIGFILENAME,                     { PATH/NAME FOR CONFIG. FILE }
  119.     DATAFILEPATH:   STRING[80];         { PATH FOR DATA FILES }
  120.  
  121.  
  122.  
  123. (*
  124.     OPEN WINDOW, DISPLAY ERROR MESSAGE, WAIT FOR ESC, THEN CLOSE WINDOW.
  125. *)
  126.  
  127. PROCEDURE DISPLAYERROR(S: PROMPTSTR);
  128.  
  129.     VAR
  130.         C:  CHAR;
  131.  
  132.     BEGIN
  133.         OPENWINDOW(4);
  134.         WRITEWINDOW(JUSTC(S,38));
  135.         GOTOXY(1,2);
  136.         WRITEWINDOW(JUSTC('Press ESC to continue',38));
  137.         WRITE(BEL);
  138.         REPEAT UNTIL READKEY=ESC;
  139.         CLOSEWINDOW(4);
  140.     END;
  141.  
  142.  
  143. {$F+}
  144.  
  145. (*
  146.     CRITICAL ERROR HANDLER.  OPEN WINDOW, DISPLAY ERROR MESSAGE, AND WAIT
  147.     FOR INPUT OF (R)ETRY OR (A)BORT.  RETURN SELECTION TO DOS.
  148. *)
  149.  
  150. PROCEDURE CRTCLERRHANDLER(FLAGS,CS,IP,AX,BX,CX,DX,SI,DI,DS,ES,BP: WORD);
  151.     INTERRUPT;
  152.  
  153.     VAR
  154.         C:  CHAR;
  155.  
  156.     BEGIN
  157.         INLINE($FB);                    { ENABLE INTERRUPTS }
  158.         OPENWINDOW(5);                  { OPEN ERROR WINDOW, GET RESPONSE }
  159.         WRITEWINDOW(JUSTC(CRITICALERRORMSG(DI),38));
  160.         GOTOXY(1,2);
  161.         WRITEWINDOW(JUSTC('Retry or Abort?  (R/A)',38));
  162.         WRITE(BEL);
  163.         REPEAT
  164.             C:=UPCASE(READKEY);
  165.         UNTIL C IN ['R','A'];
  166.         CLOSEWINDOW(5);                 { CLOSE WINDOW, RETURN OPTION TO DOS }
  167.         IF C='R' THEN AX:=(AX AND $FF00)+1 ELSE AX:=(AX AND $FF00)+2;
  168.     END;
  169.  
  170.  
  171. (*
  172.     ERROR HANDLER FOR ON-LINE HELP SYSTEM.
  173.     IF HELP FILE NOT FOUND, RUN WITHOUT HELP.  FOR ALL OTHER ERRORS,
  174.     DISPLAY ERROR, WAIT FOR ESC THEN CONTINUE WITHOUT HELP SYSTEM.
  175. *)
  176.  
  177. PROCEDURE HELPERRHANDLER(ERRCODE: BYTE);
  178.  
  179.     VAR
  180.         W:  BYTE;
  181.  
  182.     BEGIN
  183.         HELPONLINE:=FALSE;
  184.         W:=CURRENTWINDOW;
  185.         SELECTWINDOW(9);
  186.         CLRSCR;
  187.         WRITE('No help');
  188.         SELECTWINDOW(W);
  189.         IF ERRCODE<>CONERRNOHELPFILE THEN
  190.             DISPLAYERROR('Error in on-line help system');
  191.     END;
  192.  
  193.  
  194. (*
  195.     ERROR HANDLING ROUTINES FOR EDIT FUNCTIONS.  DISPLAY APPROPRIATE ERROR
  196.     MESSAGE AND WAIT FOR ESC TO CONTINUE.
  197. *)
  198.  
  199. PROCEDURE EDITERRMONEY(W: BYTE);    { ERROR HANDLER FOR MONEY EDITS }
  200.  
  201.     BEGIN
  202.         DISPLAYERROR('Amount entered is not acceptable');
  203.     END;
  204.  
  205.  
  206. PROCEDURE EDITERRCHECKNUM(W: BYTE); { ERROR HANDLER FOR CHECK NUMBER EDITS }
  207.  
  208.     BEGIN
  209.         DISPLAYERROR('Invalid check number');
  210.     END;
  211.  
  212.  
  213. PROCEDURE EDITERRAUTONUM(W: BYTE);  { ERROR HANDLER FOR AUTO NUMERICS }
  214.  
  215.     BEGIN
  216.         DISPLAYERROR('Number entered is not acceptable');
  217.     END;
  218.  
  219.  
  220. PROCEDURE EDITERRDATE(W: BYTE);     { ERROR HANDLER FOR DATE EDITS }
  221.  
  222.     BEGIN
  223.         DISPLAYERROR('Invalid date entered');
  224.     END;
  225.  
  226. {$F-}
  227.  
  228.  
  229.  
  230.  
  231. (*
  232.     CHECK I/O RESULT CODE FOR DISK ERRORS.  IF AN ERROR HAS OCCURRED, SHOW
  233.     APPROPRIATE MESSAGE, WAIT FOR ESC, THEN ABORT PROGRAM.
  234. *)
  235.  
  236. PROCEDURE DISKCHECK(ERRCODE: BYTE);     { DISPLAY DISK ERROR AND ABORT }
  237.  
  238.     VAR
  239.         S:  PROMPTSTR;
  240.  
  241.     BEGIN
  242.         CASE ERRCODE OF                     { SET ERROR MESSAGE }
  243.             0:    EXIT;
  244.             2:    S:='File not found';
  245.             3:    S:='Path not found';
  246.             5:    S:='File access denied';
  247.             100:  S:='Disk read error';
  248.             101:  S:='Disk write error';
  249.         ELSE
  250.             S:='Disk error';
  251.         END;
  252.         HELPCONTEXT:=17;
  253.         OPENWINDOW(4);                      { DISPLAY ERROR, WAIT FOR ESC }
  254.         WRITEWINDOW(JUSTC(S,38));
  255.         GOTOXY(1,2);
  256.         WRITEWINDOW(JUSTC('Press ESC to terminate',38));
  257.         WRITE(BEL);
  258.         REPEAT
  259.         UNTIL READKEY=ESC;
  260.         CLOSEWINDOW(4);
  261.         HALT(1);                            { ABORT PROGRAM }
  262.     END;
  263.  
  264.  
  265. (*
  266.     REMOVE ALL CONSOLE WINDOW DEFINITIONS READY FOR REDEFINITION.
  267. *)
  268.  
  269.  
  270. PROCEDURE PURGEALLWINDOWS;
  271.  
  272.     VAR
  273.         K:  BYTE;
  274.  
  275.     BEGIN
  276.         FOR K:=1 TO 9 DO
  277.             PURGEWINDOW(K);
  278.     END;
  279.  
  280.  
  281. (*
  282.     SET UP ALL CONSOLE EDIT AND WINDOW DISPLAY OPTIONS.
  283. *)
  284.  
  285. PROCEDURE DEFINECONSOLEIO;
  286.  
  287.     BEGIN
  288.         WITH MONEYEDIT DO       { SETTING FOR EDITING FIELDS ON DISPLAY }
  289.             BEGIN
  290.                 ATTRIBUTE:=0;
  291.                 STARTCHAR:=#16; ENDCHAR:=#17; MARKERATTR:=HIGHCOLOR;
  292.                 ALLOWCHARS:=STANDARDCHARS;
  293.                 EXITKEYS:=TRANSKEYS;
  294.                 EDITKEY:=NUL; RESTOREKEY:=NUL; ABORTKEY:=ESC;
  295.                 NUMFORMAT:=MNYLFORMAT;
  296.                 SIGNALERROR:=EDITERRMONEY;
  297.                 FLAGS:=EDFLAGINSSTAT+EDFLAGFIRSTCLR+EDFLAGHIDECRSR;
  298.             END;
  299.         ACTYPEEDIT:=MONEYEDIT;
  300.         WITH ACTYPEEDIT DO
  301.             BEGIN
  302.                 ALLOWCHARS:=[];
  303.                 EXITKEYS:=EXITKEYS+[#32];
  304.             END;
  305.         ACNAMEEDIT:=MONEYEDIT;
  306.         ACNAMEEDIT.FLAGS:=ACNAMEEDIT.FLAGS+EDFLAGTRIML+EDFLAGTRIMR;
  307.         ACREFEDIT:=MONEYEDIT;
  308.         WITH ACREFEDIT DO
  309.             BEGIN
  310.                 ALLOWCHARS:=['A'..'Z',#32];
  311.                 FLAGS:=FLAGS+EDFLAGUPPER+EDFLAGPADR;
  312.             END;
  313.         TRANSDATEEDIT:=MONEYEDIT;
  314.         TRANSDATEEDIT.EXITKEYS:=TRANSKEYS+['+','-'];
  315.         TRANSDATEEDIT.SIGNALERROR:=EDITERRDATE;
  316.         CHECKNUMEDIT:=MONEYEDIT;
  317.         WITH CHECKNUMEDIT DO
  318.             BEGIN
  319.                 NUMFORMAT:=CHKFORMAT;
  320.                 SIGNALERROR:=EDITERRCHECKNUM;
  321.             END;
  322.         APMONEYEDIT:=MONEYEDIT;
  323.         WITH APMONEYEDIT DO
  324.             BEGIN
  325.                 EXITKEYS:=[CR,KEYF3,KEYF4];
  326.                 NUMFORMAT:=MNYZFORMAT;
  327.             END;
  328.         AUTODETAILEDIT:=ACNAMEEDIT;
  329.         WITH AUTODETAILEDIT DO
  330.             EXITKEYS:=AUTOKEYS;
  331.         AUTOMONEYEDIT:=MONEYEDIT;
  332.         WITH AUTOMONEYEDIT DO
  333.             BEGIN
  334.                 EXITKEYS:=AUTOKEYS;
  335.                 NUMFORMAT:=MNYLZFORMAT;
  336.             END;
  337.         AUTODATEEDIT:=TRANSDATEEDIT;
  338.         AUTODATEEDIT.EXITKEYS:=AUTOKEYS+['+','-'];
  339.         AUTONUMEDIT:=MONEYEDIT;
  340.         WITH AUTONUMEDIT DO
  341.             BEGIN
  342.                 EXITKEYS:=AUTOKEYS;
  343.                 NUMFORMAT:='4';
  344.                 SIGNALERROR:=EDITERRAUTONUM;
  345.             END;
  346.         AUTOINTERVALEDIT:=ACREFEDIT;
  347.         WITH AUTOINTERVALEDIT DO
  348.             BEGIN
  349.                 ALLOWCHARS:=[];
  350.                 EXITKEYS:=AUTOKEYS+[#32];
  351.             END;
  352.         WITH STATWINDOW DO      { WINDOW FOR TOP STATUS LINE }
  353.             BEGIN
  354.                 X1:=1;  Y1:=1;
  355.                 X2:=80; Y2:=1;
  356.                 DEFAULTATTR:=STATCOLOR;
  357.                 DEFAULTCRSRHIDE:=TRUE; DEFAULTCRSRSIZE:=WCRSRDEFAULT;
  358.                 FLAGS:=WFLAGCLROPEN;
  359.             END;
  360.         WITH MAINWINDOW DO      { WINDOW FOR MAIN DISPLAY AREA }
  361.             BEGIN
  362.                 X1:=1;  Y1:=5;
  363.                 X2:=80; Y2:=24;
  364.                 DEFAULTATTR:=MAINCOLOR;
  365.                 DEFAULTCRSRHIDE:=TRUE; DEFAULTCRSRSIZE:=WCRSRDEFAULT;
  366.                 FLAGS:=WFLAGCLROPEN;
  367.             END;
  368.         WITH PROMPTWINDOW DO    { POP-UP WINDOW FOR OCCASIONAL QUESTIONS }
  369.             BEGIN
  370.                 X1:=20; Y1:=12;
  371.                 X2:=60; Y2:=15;
  372.                 DEFAULTATTR:=MAINCOLOR;
  373.                 DEFAULTCRSRHIDE:=TRUE; DEFAULTCRSRSIZE:=WCRSRDEFAULT;
  374.                 BORDER:=WBORDER1; BORDERATTR:=HIGHCOLOR;
  375.                 HDRTEXT:=''; FTRTEXT:='';
  376.                 FLAGS:=WFLAGCLROPEN+WFLAGRESTORE+WFLAGSHOWBRDR;
  377.             END;
  378.         EDITERRWINDOW:=PROMPTWINDOW;    { POP-UP WINDOW FOR EDITING ERRORS }
  379.         WITH CRTCLWINDOW DO             { POP-UP WINDOW FOR CRITICAL ERRORS }
  380.             BEGIN
  381.                 X1:=20; Y1:=12;
  382.                 X2:=60; Y2:=15;
  383.                 DEFAULTATTR:=MAINCOLOR;
  384.                 DEFAULTCRSRHIDE:=TRUE; DEFAULTCRSRSIZE:=WCRSRDEFAULT;
  385.                 BORDER:=WBORDER2; BORDERATTR:=HIGHCOLOR;
  386.                 HDRTEXT:='CRITICAL ERROR';
  387.                 HDRATTR:=HIGHCOLOR; HDRPOS:=WJUSTLEFT;
  388.                 FTRTEXT:='';
  389.                 FLAGS:=WFLAGCLROPEN+WFLAGRESTORE+WFLAGSHOWBRDR;
  390.             END;
  391.         WITH VIEWWINDOW DO      { DISPLAY AREA FOR ACCOUNT TRANSACTIONS }
  392.             BEGIN
  393.                 X1:=1;  Y1:=12;
  394.                 X2:=80; Y2:=23;
  395.                 DEFAULTATTR:=MAINCOLOR;
  396.                 DEFAULTCRSRHIDE:=TRUE; DEFAULTCRSRSIZE:=WCRSRDEFAULT;
  397.                 FLAGS:=WFLAGCLROPEN+WFLAGRESTORE;
  398.             END;
  399.         ENTERWINDOW:=VIEWWINDOW;    { TRANSACTION/AUTO ENTRIES EDITING }
  400.         ENTERWINDOW.Y1:=11;
  401.         WITH OPTLINEWINDOW DO       { OPTION REMINDER LINE WINDOW }
  402.             BEGIN
  403.                 X1:=17; Y1:=24;
  404.                 X2:=80; Y2:=25;
  405.                 DEFAULTATTR:=MAINCOLOR;
  406.                 DEFAULTCRSRHIDE:=TRUE; DEFAULTCRSRSIZE:=WCRSRDEFAULT;
  407.                 FLAGS:=WFLAGCLROPEN;
  408.             END;
  409.         WITH HELPSTATWINDOW DO
  410.             BEGIN
  411.                 X1:=1;  Y1:=25;
  412.                 X2:=10; Y2:=25;
  413.                 DEFAULTATTR:=MAINCOLOR;
  414.                 DEFAULTCRSRHIDE:=TRUE; DEFAULTCRSRSIZE:=WCRSRDEFAULT;
  415.                 FLAGS:=WFLAGCLROPEN;
  416.             END;
  417.         DEFINEWINDOW(1,STATWINDOW);
  418.         DEFINEWINDOW(2,MAINWINDOW);
  419.         DEFINEWINDOW(3,PROMPTWINDOW);
  420.         DEFINEWINDOW(4,EDITERRWINDOW);
  421.         DEFINEWINDOW(5,CRTCLWINDOW);
  422.         DEFINEWINDOW(6,VIEWWINDOW);
  423.         DEFINEWINDOW(7,OPTLINEWINDOW);
  424.         DEFINEWINDOW(8,ENTERWINDOW);
  425.         DEFINEWINDOW(9,HELPSTATWINDOW);
  426.     END;  { DEFINECONSOLEIO }
  427.  
  428.  
  429. (*
  430.     READ CONFIGURATION FILE, IF PRESENT, AND SET OPTIONS.
  431.     CONFIGURABLE OPTIONS ARE DATA, PRINT, DATE, AND COLORS.
  432. *)
  433.  
  434. PROCEDURE READCONFIGURATION;
  435.  
  436.     VAR
  437.         F:  TEXT;
  438.         C,
  439.         R:  INTEGER;
  440.         S1,
  441.         S2,
  442.         S3: STRING[80];
  443.  
  444.     BEGIN
  445.         {$I-}
  446.         ASSIGN(F,CONFIGFILENAME);           { OPEN CONFIG. FILE }
  447.         RESET(F);
  448.         R:=IORESULT;
  449.         IF (R=2) AND (PARAMCOUNT=0) THEN    { IF NOT EXPLICITLY SPECIFIED }
  450.             EXIT                            { AND NOT PRESENT, SKIP ROUTINE }
  451.         ELSE
  452.             DISKCHECK(R);
  453.         WHILE NOT(EOF(F)) DO                { GET EACH OPTION LINE }
  454.             BEGIN
  455.                 READLN(F,S1);
  456.                 S1:=UPPERCASE(TRIML(TRIMR(S1)));
  457.                 S2:=TRIMR(PRECEDE(S1,'='));
  458.                 S3:=TRIML(FOLLOW(S1,'='));
  459.                 IF S2='DATA' THEN           { SET PATH FOR DATA FILES }
  460.                     DATAFILEPATH:=S3;
  461.                 IF S2='PRINT' THEN          { SET PATH/FILE FOR PRINTING }
  462.                     IF S3<>'' THEN
  463.                         ASSIGN(PRN,S3);
  464.                 IF S2='DATE' THEN           { SET REQUIRED DATE FORMAT }
  465.                     IF S3='MDY' THEN
  466.                         BEGIN
  467.                             DATEFORMAT:=DATEFORMMDY;
  468.                             DATEDELIMITER:='/';
  469.                         END
  470.                     ELSE
  471.                         IF S3='DMY' THEN
  472.                             BEGIN
  473.                                 DATEFORMAT:=DATEFORMDMY;
  474.                                 DATEDELIMITER:='.';
  475.                             END;
  476.                 IF S2='CURRENCY' THEN       { SET CURRENCY SYMBOL }
  477.                     BEGIN
  478.                         VAL(S3,C,R);
  479.                         FORMATCONFIG.CURRENCY:=CHR(C);
  480.                     END;
  481.                 IF S2='COLORS' THEN         { SET DISPLAY ATTRIBUTES }
  482.                     BEGIN
  483.                         S2:=SPAN(S3,DECDIGITS);
  484.                         VAL(S2,MAINCOLOR,R);
  485.                         S2:=BREAK(S3,DECDIGITS);
  486.                         S2:=SPAN(S3,DECDIGITS);
  487.                         VAL(S2,HIGHCOLOR,R);
  488.                         S2:=BREAK(S3,DECDIGITS);
  489.                         S2:=SPAN(S3,DECDIGITS);
  490.                         VAL(S2,TITLECOLOR,R);
  491.                         S2:=BREAK(S3,DECDIGITS);
  492.                         S2:=SPAN(S3,DECDIGITS);
  493.                         VAL(S2,STATCOLOR,R);
  494.                     END;
  495.             END;  { WHILE }
  496.         CLOSE(F); DISKCHECK(IORESULT);
  497.         {$I+}
  498.     END;  { READCONFIGURATION }
  499.  
  500.  
  501.  
  502. (*
  503.     OPEN WINDOW, SHOW TWO LINE PROMPT, THEN WAIT FOR (Y)ES OR (N)O RESPONSE.
  504.     RETURN TRUE IF YES, FALSE IF NO OR ESC.
  505. *)
  506.  
  507. FUNCTION GETYESNO(S1,S2: PROMPTSTR): BOOLEAN;
  508.  
  509.     VAR
  510.         C:  CHAR;
  511.  
  512.     BEGIN
  513.         OPENWINDOW(3);
  514.         WRITEWINDOW(JUSTC(S1,38));
  515.         GOTOXY(1,2);
  516.         WRITEWINDOW(JUSTC(S2+'  (Y/N)',38));
  517.         REPEAT
  518.             C:=UPCASE(READKEY);
  519.         UNTIL C IN ['Y','N',ESC];
  520.         GETYESNO:=(C='Y');
  521.         CLOSEWINDOW(3);
  522.     END;  { GETYESNO }
  523.  
  524.  
  525. (*
  526.     UPDATE ACCOUNTS STATUS FILE WITH CURRENT ACCOUNT RECORDS.
  527. *)
  528.  
  529. PROCEDURE UPDATEACSTATFILE;
  530.  
  531.     VAR
  532.         C: CHAR;
  533.  
  534.     BEGIN
  535.         {$I-}
  536.         SEEK(ACSTATFILE,0); DISKCHECK(IORESULT);
  537.         FOR C:='A' TO 'Z' DO
  538.             BEGIN
  539.                 WRITE(ACSTATFILE,ACSTATUS[C]); DISKCHECK(IORESULT);
  540.             END;
  541.         {$I+}
  542.     END;
  543.  
  544.  
  545. (*
  546.     INITIALIZE STATUS RECORD FOR EACH ACCOUNT.
  547.     IF DATA FILE IS FOUND, READ ACCOUNT DATA FROM FILE, OTHERWISE PROMPT USER
  548.     TO CREATE A NEW ACCOUNTS SYSTEM AND INITIALIZE ALL ACCOUNTS TO UNUSED.
  549.     RETURNS TRUE IF SUCCESSFUL, FALSE IF FILE NOT FOUND AND USER DOES NOT
  550.     REQUEST NEW SYSTEM TO BE SET UP.
  551. *)
  552.  
  553. FUNCTION ACSTATINIT: BOOLEAN;
  554.  
  555.     VAR
  556.         C:  CHAR;
  557.         B:  BOOLEAN;
  558.         R:  BYTE;
  559.  
  560.     BEGIN
  561.         {$I-}
  562.         RESET(ACSTATFILE);              { ATTEMPT TO OPEN STATUS FILE }
  563.         R:=IORESULT;
  564.         CASE R OF
  565.             0:  BEGIN                   { IF FOUND, READ ACCOUNT RECORDS }
  566.                     FOR C:='A' TO 'Z' DO
  567.                         BEGIN
  568.                             READ(ACSTATFILE,ACSTATUS[C]); DISKCHECK(IORESULT);
  569.                         END;
  570.                     ACSTATINIT:=TRUE;
  571.                 END;
  572.             2:  BEGIN                   { IF NOT FOUND, CREATE NEW RECORDS }
  573.                     B:=GETYESNO('Accounts data not found',
  574.                                 'Create new accounts records?');
  575.                     IF B THEN
  576.                         BEGIN
  577.                             FOR C:='A' TO 'Z' DO
  578.                               WITH ACSTATUS[C] DO
  579.                                   BEGIN
  580.                                       NAME:='';
  581.                                       ACTYPE:=UNUSED;
  582.                                       RECBAL:=0;
  583.                                       UNRECBAL:=0;
  584.                                       CHECKNUM:=1;
  585.                                       DRDEFAULT:='';
  586.                                       CRDEFAULT:='';
  587.                                   END;
  588.                             REWRITE(ACSTATFILE); DISKCHECK(IORESULT);
  589.                             UPDATEACSTATFILE;
  590.                         END;
  591.                     ACSTATINIT:=B;
  592.                 END;
  593.           ELSE                          { IF ANY OTHER ERROR, ABORT PROGRAM }
  594.               DISKCHECK(R);
  595.         END;  { CASE R }
  596.         {$I+}
  597.     END;  { ACSTATINIT }
  598.  
  599.  
  600. (*
  601.     READ A SPECIFIED TRANSACTION NUMBER FROM TRANSFILE.
  602. *)
  603.  
  604. PROCEDURE READTRANS(REC: LONGINT; VAR TRANS: TRANSREC);
  605.  
  606.     BEGIN
  607.         {$I-}
  608.         SEEK(TRANSFILE,REC); DISKCHECK(IORESULT);
  609.         READ(TRANSFILE,TRANS); DISKCHECK(IORESULT);
  610.         {$I+}
  611.     END;
  612.  
  613.  
  614. (*
  615.     WRITE A TRANSACTION TO A SPECIFIED POSITION IN TRANSFILE.
  616. *)
  617.  
  618. PROCEDURE WRITETRANS(REC: LONGINT; TRANS: TRANSREC);
  619.  
  620.     BEGIN
  621.         {$I-}
  622.         SEEK(TRANSFILE,REC); DISKCHECK(IORESULT);
  623.         WRITE(TRANSFILE,TRANS); DISKCHECK(IORESULT);
  624.         {$I+}
  625.     END;
  626.  
  627.  
  628.  
  629. (*
  630.     ADD TRANSACTION TO CURRENTLY OPEN TRANSACTION FILE.
  631.     INSERTS TRANSACTION IN CORRECT CHRONOLOGICAL ORDER, SHIFTING LATER
  632.     TRANSACTIONS FORWARD AND ADJUSTING BALANCES ACCORDINGLY.
  633.     AMENDS ACCOUNT RECORD PASSED IN AC TO REFLECT NEW BALANCE.
  634. *)
  635.  
  636. PROCEDURE ADDTRANS(VAR AC: ACCOUNTREC; TRANS: TRANSREC);
  637.  
  638.     VAR
  639.         T1,T2:  TRANSREC;
  640.         I,J,K:  LONGINT;
  641.  
  642.     BEGIN
  643.         WITH AC DO
  644.             IF TRANS.RECON=UNREC THEN       { UPDATE ACCOUNT BALANCE }
  645.                 UNRECBAL:=UNRECBAL+TRANS.AMOUNT
  646.             ELSE
  647.                 RECBAL:=RECBAL+TRANS.AMOUNT;
  648.         I:=FILESIZE(TRANSFILE);             { GET LOCATION OF LAST RECORD }
  649.         J:=I;
  650.         REPEAT                              { FIND CORRECT CHRONOLOGICAL POS. }
  651.             DEC(I);
  652.             READTRANS(I,T1);
  653.         UNTIL (T1.DATE<=TRANS.DATE) OR (T1.RECON=BAL);
  654.         T2:=TRANS;
  655.         REPEAT                              { ADJUST FOLLOWING TRANSACTIONS }
  656.             T2.BALANCE:=T1.BALANCE+T2.AMOUNT;
  657.             INC(I);
  658.             IF I<J THEN
  659.                 READTRANS(I,T1);
  660.             WRITETRANS(I,T2);
  661.             TRANS:=T1; T1:=T2; T2:=TRANS;
  662.         UNTIL I=J;
  663.     END;  { ADDTRANS }
  664.  
  665.  
  666.  
  667. (*
  668.     LIST ACCOUNT NAMES AND IDENTIFIERS.
  669. *)
  670.  
  671. PROCEDURE LISTACCOUNTS;
  672.  
  673.     VAR
  674.         C:  CHAR;
  675.  
  676.     BEGIN
  677.         CLRSCR;
  678.         FOR C:='A' TO 'M' DO
  679.             WRITELN(' ',C,'':3,PADR(ACSTATUS[C].NAME,40),
  680.                     CHR(ORD(C)+13),'':3,ACSTATUS[CHR(ORD(C)+13)].NAME);
  681.         GOTOXY(1,20);
  682.     END;  { LISTACCOUNTS }
  683.  
  684.  
  685. (*
  686.     LIST OPTIONS ON LAST LINE OF DISPLAY.
  687. *)
  688.  
  689. PROCEDURE SHOWOPTIONS(K1,S1,K2,S2,K3,S3,K4,S4: PROMPTSTR);
  690.  
  691.     VAR
  692.         W:  BYTE;
  693.  
  694.     BEGIN
  695.         W:=CURRENTWINDOW;
  696.         SELECTWINDOW(7);
  697.         CLRSCR;
  698.         GOTOXY(1,2);
  699.         TEXTATTR:=HIGHCOLOR; WRITE(K1);
  700.         TEXTATTR:=MAINCOLOR; WRITE(#32,S1);
  701.         GOTOXY(17,2);
  702.         TEXTATTR:=HIGHCOLOR; WRITE(K2);
  703.         TEXTATTR:=MAINCOLOR; WRITE(#32,S2);
  704.         GOTOXY(33,2);
  705.         TEXTATTR:=HIGHCOLOR; WRITE(K3);
  706.         TEXTATTR:=MAINCOLOR; WRITE(#32,S3);
  707.         GOTOXY(49,2);
  708.         TEXTATTR:=HIGHCOLOR; WRITE(K4);
  709.         TEXTATTR:=MAINCOLOR; WRITE(#32,S4);
  710.         SELECTWINDOW(W);
  711.     END;  { SHOWOPTIONS }
  712.  
  713.  
  714. (*
  715.     DISPLAY MAIN MENU, RETURN USER'S OPTION.
  716. *)
  717.  
  718. FUNCTION MAINMENU: CHAR;
  719.  
  720.     VAR
  721.         D:  DATEREC;
  722.         C:  CHAR;
  723.  
  724.     BEGIN
  725.         GETTODAY(D);
  726.         SELECTWINDOW(1);                    { DISPLAY TITLE & DATE }
  727.         CLRSCR;
  728.         WRITE(PADR('HOME ACCOUNTS',70),DATESTR(D));
  729.         SELECTWINDOW(2);
  730.         LISTACCOUNTS;                       { SHOW LIST OF ACCOUNTS }
  731.         SHOWOPTIONS('F3','Summary',         { SHOW OPTIONS }
  732.                     'A-Z','Select',
  733.                     'F4', 'Maint.',
  734.                     'F10','Quit');
  735.         REPEAT
  736.             C:=UPCASE(READKEY);             { INPUT/RETURN CHOICE }
  737.         UNTIL C IN ['A'..'Z',KEYF3,KEYF4,KEYF10];
  738.         MAINMENU:=C;
  739.     END;  { MAINMENU }
  740.  
  741.  
  742. (*
  743.     CONVERT TRANSACTION RECORD TO PRINTABLE STRING.
  744. *)
  745.  
  746. FUNCTION TRANSTOSTR(T: TRANSREC): STRING;
  747.  
  748.     CONST
  749.         RECCHAR =   '*';        { UNRECONCILED MARKER CHARACTER }
  750.  
  751.     VAR
  752.         S:  STRING[80];
  753.         D:  DATEREC;
  754.  
  755.     BEGIN
  756.         WITH T DO
  757.             BEGIN
  758.                 WORDTODATE(DATE,D);
  759.                 IF RECON=BAL THEN
  760.                     S:=DUPLCHAR(#32,11)
  761.                 ELSE
  762.                     S:=' '+DATESTR(D)+'  ';
  763.                 S:=S+PADR(DETAIL,DETAILLEN)+' ';
  764.                 IF RECON=BAL THEN
  765.                     S:=S+DUPLCHAR(#32,29)
  766.                 ELSE
  767.                     IF AMOUNT>0 THEN
  768.                         S:=S+DUPLCHAR(#32,15)+FORMAT(AMOUNT/100,MNYFORMAT)
  769.                     ELSE
  770.                         S:=S+FORMAT(-AMOUNT/100,MNYFORMAT)+DUPLCHAR(#32,15);
  771.                 S:=S+' '+FORMAT(BALANCE/100,MNYZFORMAT)+'  ';
  772.                 IF RECON=UNREC THEN
  773.                     S:=S+'*'
  774.                 ELSE
  775.                     S:=S+' ';
  776.             END;
  777.         TRANSTOSTR:=S;
  778.     END;  { TRANSTOSTR }
  779.  
  780.  
  781. (*
  782.     DELETE RECORD FROM AUTO-ENTRIES FILE, SHIFT RECORDS, AND TRUNCATE FILE.
  783. *)
  784.  
  785. PROCEDURE DELETEAUTOTRANSENTRY(I: LONGINT);
  786.  
  787.     VAR
  788.         T:  AUTOREC;
  789.  
  790.     BEGIN
  791.         {$I-}
  792.         INC(I);
  793.         WHILE (I<FILESIZE(AUTOFILE)) DO
  794.             BEGIN
  795.                 SEEK(AUTOFILE,I); DISKCHECK(IORESULT);
  796.                 READ(AUTOFILE,T); DISKCHECK(IORESULT);
  797.                 SEEK(AUTOFILE,I-1); DISKCHECK(IORESULT);
  798.                 WRITE(AUTOFILE,T); DISKCHECK(IORESULT);
  799.                 INC(I);
  800.             END;
  801.         DEC(I);
  802.         SEEK(AUTOFILE,I); DISKCHECK(IORESULT);
  803.         TRUNCATE(AUTOFILE); DISKCHECK(IORESULT);
  804.         {$I-}
  805.     END;
  806.  
  807.  
  808. (*
  809.     MAIN MENU OPTION TO ACCESS SPECIFIED ACCOUNT.
  810.     RETURNS KEY CODE THAT CAUSED MAIN LOOP TO TERMINATE.
  811. *)
  812.  
  813. FUNCTION ACCESSACCOUNT(ID: CHAR): CHAR;
  814.  
  815.     VAR
  816.         CURDATE:    DATEREC;        { CURRENT DATE }
  817.         TRANS:      TRANSREC;
  818.         F5TRANS,                    { IDENTIFYING STRINGS FOR F5/F6 KEYS }
  819.         F6TRANS:    STRING[10];
  820.         TOPTRANS:   LONGINT;        { REC. NUMBER OF TRANS. AT TOP OF WINDOW }
  821.         CRSROFFSET: BYTE;           { OFFSET FROM WINDOW TOP TO CURSOR }
  822.         OPT:        CHAR;
  823.         SAVEDHC:    BYTE;
  824.         B:          BOOLEAN;
  825.  
  826.  
  827.     PROCEDURE SHOWBAL;        { UPDATE DISPLAY OF REC./UNREC. BALANCES }
  828.  
  829.         CONST
  830.             TCOL = 48;          { COLUMN FOR BALANCE TITLES }
  831.             FCOL = 63;          { COLUMN FOR BALANCE FIELDS }
  832.  
  833.         VAR
  834.             W:  BYTE;
  835.  
  836.         BEGIN
  837.             W:=CURRENTWINDOW;
  838.             SELECTWINDOW(2);
  839.             WITH ACSTATUS[ID] DO
  840.                 BEGIN
  841.                     GOTOXY(TCOL,1);
  842.                     WRITE('Reconciled     ',
  843.                         FORMAT(RECBAL/100,MNYZFORMAT));
  844.                     GOTOXY(TCOL,2);
  845.                     WRITE('Unreconciled   ',
  846.                         FORMAT(UNRECBAL/100,MNYZFORMAT),'  *');
  847.                     GOTOXY(FCOL,3);
  848.                     WRITE(DUPLCHAR(#196,14));
  849.                     GOTOXY(TCOL,4);
  850.                     WRITE('Balance        ',
  851.                         FORMAT((RECBAL+UNRECBAL)/100,MNYDFORMAT));
  852.                     GOTOXY(FCOL,5);
  853.                     WRITE(DUPLCHAR(#205,14));
  854.                 END;
  855.             SELECTWINDOW(W);
  856.         END;  { SHOWBAL }
  857.  
  858.  
  859.     PROCEDURE TRANSPAGE;                { DISPLAY PAGE OF TRANSACTIONS }
  860.  
  861.         VAR
  862.             T:  TRANSREC;
  863.             FS: LONGINT;
  864.             I:  BYTE;
  865.  
  866.         BEGIN
  867.             CLRSCR;
  868.             FS:=FILESIZE(TRANSFILE)-1;
  869.             FOR I:=0 TO 11 DO
  870.                 BEGIN
  871.                     READTRANS(TOPTRANS+I,T);
  872.                     GOTOXY(1,I+1);
  873.                     WRITEWINDOW(TRANSTOSTR(T));
  874.                     IF TOPTRANS+I=FS THEN EXIT;
  875.                 END;
  876.         END;  { TRANSPAGE }
  877.  
  878.  
  879.     PROCEDURE MARKTRANS(M: BOOLEAN);    { SET/CLEAR TRANSACTION MARKERS }
  880.  
  881.         BEGIN
  882.             GOTOXY(1,CRSROFFSET+1);
  883.             IF M THEN
  884.                 BEGIN
  885.                     TEXTATTR:=HIGHCOLOR; WRITEWINDOW(#16);
  886.                 END
  887.             ELSE
  888.                 WRITEWINDOW(#32);
  889.             GOTOXY(80,CRSROFFSET+1);
  890.             IF M THEN
  891.                 BEGIN
  892.                     TEXTATTR:=HIGHCOLOR; WRITEWINDOW(#17);
  893.                 END
  894.             ELSE
  895.                 WRITEWINDOW(#32);
  896.             TEXTATTR:=MAINCOLOR;
  897.         END;  { MARKTRANS }
  898.  
  899.  
  900.     { MOVE FORWARD TO NEXT TRANSACTION.
  901.       RETURN TRUE IF SUCCESSFUL, FALSE IF ALREADY AT LAST TRANSACTION. }
  902.  
  903.     FUNCTION NEXTTRANS: BOOLEAN;
  904.  
  905.         BEGIN
  906.             NEXTTRANS:=TRUE;
  907.             IF TOPTRANS+CRSROFFSET+1<FILESIZE(TRANSFILE) THEN
  908.                 IF CRSROFFSET<11 THEN
  909.                     INC(CRSROFFSET)
  910.                 ELSE
  911.                     BEGIN
  912.                         INC(TOPTRANS);
  913.                         GOTOXY(1,1);
  914.                         DELLINE;
  915.                         GOTOXY(1,12);
  916.                         READTRANS(TOPTRANS+11,TRANS);
  917.                         WRITEWINDOW(TRANSTOSTR(TRANS));
  918.                     END
  919.             ELSE
  920.                 BEGIN
  921.                     WRITE(BEL);
  922.                     NEXTTRANS:=FALSE;
  923.                 END;
  924.         END;  { NEXTTRANS }
  925.  
  926.  
  927.     { MOVE BACK TO PREVIOUS TRANSACTION.
  928.       RETURN TRUE IF SUCCESSFUL, FALSE IF ALREADY AT START OF FILE. }
  929.  
  930.     FUNCTION PREVTRANS: BOOLEAN;
  931.  
  932.       BEGIN
  933.           PREVTRANS:=TRUE;
  934.           IF CRSROFFSET<>0 THEN
  935.               DEC(CRSROFFSET)
  936.           ELSE
  937.               IF TOPTRANS<>0 THEN
  938.                   BEGIN
  939.                       DEC(TOPTRANS);
  940.                       READTRANS(TOPTRANS,TRANS);
  941.                       GOTOXY(1,1);
  942.                       INSLINE;
  943.                       WRITEWINDOW(TRANSTOSTR(TRANS));
  944.                   END
  945.             ELSE
  946.                 BEGIN
  947.                     WRITE(BEL);
  948.                     PREVTRANS:=FALSE;
  949.                 END;
  950.       END;  { PREVTRANS }
  951.  
  952.     PROCEDURE FIRSTTRANS;       { MOVE TO FIRST TRANSACTION }
  953.  
  954.         BEGIN
  955.             TOPTRANS:=0;
  956.             CRSROFFSET:=0;
  957.             TRANSPAGE;
  958.         END;
  959.  
  960.  
  961.     PROCEDURE LASTTRANS;        { MOVE TO LAST TRANSACTION }
  962.  
  963.       BEGIN
  964.           TOPTRANS:=FILESIZE(TRANSFILE)-12;
  965.           IF TOPTRANS<0 THEN
  966.               BEGIN
  967.                   TOPTRANS:=0;
  968.                   CRSROFFSET:=FILESIZE(TRANSFILE)-1;
  969.               END
  970.           ELSE
  971.               CRSROFFSET:=11;
  972.           TRANSPAGE;
  973.       END;
  974.  
  975.  
  976.     PROCEDURE AUTOTRANS;        { EDIT LIST OF AUTOMATIC ENTRIES }
  977.  
  978.         CONST
  979.             TCOL    = 15;           { COLUMN FOR FIELD TITLES }
  980.             FCOL    = 40;           { COLUMN FOR FIELD EDITING }
  981.  
  982.         VAR
  983.             T:      AUTOREC;        { AUTO TRANSACTION RECORD }
  984.             ATN:    LONGINT;        { CURRENT AUTO TRANSACTION NUMBER }
  985.             FIELD:  BYTE;           { EDIT FIELD INDICATOR }
  986.             C:      CHAR;
  987.             S,TS:   STRING[6];
  988.             I:      LONGINT;
  989.             DMFLAG: BOOLEAN;
  990.  
  991.  
  992.         BEGIN
  993.             OPENWINDOW(8);              { SET UP DISPLAY }
  994.             TEXTATTR:=TITLECOLOR;
  995.             WRITEWINDOW(PADR('Automatic transactions',80));
  996.             TEXTATTR:=MAINCOLOR;
  997.             GOTOXY(TCOL,3); WRITE('Date');
  998.             GOTOXY(TCOL,5); WRITE('Detail');
  999.             GOTOXY(TCOL,7); WRITE('Amount');
  1000.             GOTOXY(FCOL+20,7); WRITE('(Zero for prompt)');
  1001.             GOTOXY(TCOL,10); WRITE('Number of entries');
  1002.             GOTOXY(FCOL+20,10); WRITE('(Zero for unlimited)');
  1003.             GOTOXY(TCOL,12); WRITE('Interval');
  1004.             SHOWOPTIONS(#24+#25,'Select','F4','Delete',
  1005.                             'F10','Accept','ESC','Abort');
  1006.             ATN:=FILESIZE(AUTOFILE);
  1007.             REPEAT                      { MAIN LOOP }
  1008.                 TEXTATTR:=TITLECOLOR;
  1009.                 GOTOXY(40,1); CLREOL;
  1010.                 IF ATN>=FILESIZE(AUTOFILE) THEN { CREATE NEW RECORD OR READ }
  1011.                     WITH T DO
  1012.                         BEGIN
  1013.                             DATE:=CURDATE;
  1014.                             UPDATE:=-1;
  1015.                             COUNT:=0;
  1016.                             AUTODRCR:=DEBIT;
  1017.                             AMOUNT:=0;
  1018.                             DETAIL:='';
  1019.                             WRITE('New');
  1020.                         END
  1021.                 ELSE
  1022.                     BEGIN
  1023.                         WRITE('#',ATN+1);
  1024.                         {$I-}
  1025.                         SEEK(AUTOFILE,ATN); DISKCHECK(IORESULT);
  1026.                         READ(AUTOFILE,T); DISKCHECK(IORESULT);
  1027.                         {$I+}
  1028.                     END;
  1029.                 GOTOXY(65,1); WRITE('Total: ',FILESIZE(AUTOFILE));
  1030.                 TEXTATTR:=MAINCOLOR;
  1031.                 FIELD:=0;
  1032.                 REPEAT                  { EDIT RECORD LOOP }
  1033.                     WITH T DO               { DISPLAY RECORD }
  1034.                         BEGIN
  1035.                             GOTOXY(FCOL,3);
  1036.                             WRITE(#32,DATESTR(DATE));
  1037.                             GOTOXY(FCOL,5);
  1038.                             WRITE(PADR(DETAIL,DETAILLEN));
  1039.                             GOTOXY(FCOL,7);
  1040.                             WRITE(FORMAT(AMOUNT/100,MNYLZFORMAT));
  1041.                             CASE AUTODRCR OF
  1042.                                 DEBIT:  TS:='Debit ';
  1043.                                 CREDIT: TS:='Credit';
  1044.                             END;
  1045.                             GOTOXY(FCOL,8); WRITE(TS);
  1046.                             GOTOXY(FCOL,10); WRITE(COUNT:4);
  1047.                             GOTOXY(FCOL,12);
  1048.                             IF UPDATE>0 THEN
  1049.                                 BEGIN
  1050.                                     WRITE(UPDATE:4);
  1051.                                     S:=' Days ';
  1052.                                 END
  1053.                             ELSE
  1054.                                 BEGIN
  1055.                                     WRITE(-UPDATE:4);
  1056.                                     S:='Months';
  1057.                                 END;
  1058.                             GOTOXY(FCOL,13); WRITE(S);
  1059.                             CASE FIELD OF           { CALL EDIT ROUTINES }
  1060.                                 0:  BEGIN
  1061.                                         GOTOXY(FCOL,3);
  1062.                                         REPEAT
  1063.                                             C:=EDITDATE(AUTODATEEDIT,DATE);
  1064.                                             IF C='+' THEN
  1065.                                                 ADJUSTDATE(DATE,1);
  1066.                                             IF C='-' THEN
  1067.                                                 ADJUSTDATE(DATE,-1);
  1068.                                         UNTIL NOT(C IN ['+','-']);
  1069.                                     END;
  1070.                                 1:  BEGIN
  1071.                                         GOTOXY(FCOL,5);
  1072.                                         C:=EDITSTRING(AUTODETAILEDIT,
  1073.                                                       DETAIL,DETAILLEN);
  1074.                                     END;
  1075.                                 2:  BEGIN
  1076.                                         GOTOXY(FCOL,7);
  1077.                                         C:=EDITINT(AUTOMONEYEDIT,AMOUNT,
  1078.                                                       0,MAXMONEY);
  1079.                                     END;
  1080.                                 3:  BEGIN
  1081.                                         GOTOXY(FCOL,8);
  1082.                                         C:=EDITSTRING(AUTOINTERVALEDIT,TS,6);
  1083.                                         IF C=#32 THEN
  1084.                                           BEGIN
  1085.                                             CASE AUTODRCR  OF
  1086.                                               DEBIT:  BEGIN
  1087.                                                         AUTODRCR:=CREDIT;
  1088.                                                         TS:='Credit';
  1089.                                                       END;
  1090.                                               CREDIT: BEGIN
  1091.                                                         AUTODRCR:=DEBIT;
  1092.                                                         TS:='Debit ';
  1093.                                                       END;
  1094.                                             END;  { CASE AUTODRCR }
  1095.                                             WRITE(TS);
  1096.                                           END;
  1097.                                     END;
  1098.                                 4:  BEGIN
  1099.                                         GOTOXY(FCOL,10);
  1100.                                         C:=EDITINT(AUTONUMEDIT,COUNT,0,9999);
  1101.                                     END;
  1102.                                 5:  BEGIN
  1103.                                         GOTOXY(FCOL,12);
  1104.                                         DMFLAG:=(UPDATE<0);
  1105.                                         IF DMFLAG THEN
  1106.                                             UPDATE:=-UPDATE;
  1107.                                         C:=EDITINT(AUTONUMEDIT,UPDATE,1,9999);
  1108.                                         IF DMFLAG THEN
  1109.                                             UPDATE:=-UPDATE;
  1110.                                     END;
  1111.                                 6:  BEGIN
  1112.                                         GOTOXY(FCOL,13);
  1113.                                         C:=EDITSTRING(AUTOINTERVALEDIT,S,6);
  1114.                                         IF C=#32 THEN
  1115.                                             BEGIN
  1116.                                                 UPDATE:=-UPDATE;
  1117.                                                 IF UPDATE>0 THEN
  1118.                                                     S:=' Days '
  1119.                                                 ELSE
  1120.                                                     S:='Months';
  1121.                                               WRITE(S);
  1122.                                         END;
  1123.                                     END;
  1124.                             END;  { CASE FIELD }
  1125.                             CASE C OF       { MOVE TO NEXT FIELD }
  1126.                                 KEYUP,KEYSTAB:
  1127.                                     IF FIELD=0 THEN FIELD:=6 ELSE DEC(FIELD);
  1128.                                 CR,KEYDOWN,HT:
  1129.                                     IF FIELD=6 THEN FIELD:=0 ELSE INC(FIELD);
  1130.                             END;  { CASE C }
  1131.                       END;  { WITH T }
  1132.                 UNTIL C IN
  1133.                     [KEYF10,ESC,KEYPGUP,KEYPGDN,KEYCPGUP,KEYCPGDN,KEYF4];
  1134.                 IF C=KEYF4 THEN
  1135.                     IF ATN>=FILESIZE(AUTOFILE) THEN
  1136.                         WRITE(BEL)
  1137.                     ELSE                { DELETE A RECORD }
  1138.                         BEGIN
  1139.                             IF GETYESNO('Delete automatic transaction',
  1140.                                         'Are you sure?') THEN
  1141.                               DELETEAUTOTRANSENTRY(ATN);
  1142.                         END
  1143.                 ELSE
  1144.                     BEGIN
  1145.                         IF ((ATN<FILESIZE(AUTOFILE)) AND
  1146.                             (C<>ESC)) OR (C=KEYF10) THEN
  1147.                             BEGIN           { UPDATE RECORD }
  1148.                                 {$I-}
  1149.                                 SEEK(AUTOFILE,ATN); DISKCHECK(IORESULT);
  1150.                                 WRITE(AUTOFILE,T); DISKCHECK(IORESULT);
  1151.                                 {$I+}
  1152.                             END;
  1153.                         CASE C OF           { MOVE TO NEXT RECORD }
  1154.                             KEYPGUP:    IF ATN>0 THEN
  1155.                                             DEC(ATN)
  1156.                                         ELSE
  1157.                                             ATN:=FILESIZE(AUTOFILE);
  1158.                             KEYPGDN:    IF ATN<FILESIZE(AUTOFILE) THEN
  1159.                                             INC(ATN)
  1160.                                         ELSE
  1161.                                             ATN:=0;
  1162.                             KEYCPGUP: ATN:=0;
  1163.                             KEYCPGDN: ATN:=FILESIZE(AUTOFILE);
  1164.                         END;  { CASE }
  1165.                     END;
  1166.             UNTIL C IN [KEYF10,ESC];
  1167.             CLOSEWINDOW(8);     { TIDY UP DISPLAY }
  1168.         END;  { AUTOTRANS }
  1169.  
  1170.  
  1171.     { ENTER A TRANSACTION.  RETURNS TRUE IF TRANSACTION ACCEPTED,
  1172.       FALSE IF ENTRY ABORTED. }
  1173.  
  1174.     FUNCTION ENTERTRANS: BOOLEAN;
  1175.  
  1176.         CONST
  1177.             TCOL  = 15;         { COLUMN FOR FIELD TITLES }
  1178.             FCOL  = 40;         { COLUMN FOR EDIT FIELDS }
  1179.  
  1180.         VAR
  1181.             NEWTRANS:   TRANSREC;
  1182.             VALIDAUXAC,             { CONTROL OF AUXILIARY A/C SELECTION }
  1183.             OPTCREDIT,              { CONTROL OF CREDIT A/C FIELD }
  1184.             OPTCHECKNUM,            { CONTROL OF CHECK NUMBER FIELD }
  1185.             OPTCHECKAC: BOOLEAN;    { CONTROL OF CHECKING A/C FIELD }
  1186.             D:          DATEREC;
  1187.             FIELD:      BYTE;       { POS. FOR FIELD EDITING }
  1188.             CN:         LONGINT;    { CHECK NUMBER FOR EDITING }
  1189.             PREVAC,
  1190.             AC:         STRING[1];  { CREDIT/CHECKING A/C FOR EDITING }
  1191.             C:          CHAR;
  1192.  
  1193.         BEGIN
  1194.             OPENWINDOW(8);                { SET UP ENTRY AREA OF DISPLAY }
  1195.             WITH NEWTRANS DO              { INITIALIZE NEW TRANSACTION RECORD }
  1196.                 BEGIN
  1197.                     DATE:=DATETOWORD(CURDATE);
  1198.                     AMOUNT:=0;
  1199.                     RECON:=UNREC;
  1200.                     WITH ACSTATUS[ID] DO
  1201.                         CASE OPT OF
  1202.                             KEYF7:  DETAIL:=DRDEFAULT;
  1203.                             KEYF8:  DETAIL:=CRDEFAULT;
  1204.                         ELSE
  1205.                             DETAIL:='';
  1206.                         END;
  1207.                 END;  { WITH NEWTRANS }
  1208.             TEXTATTR:=TITLECOLOR;         { DISPLAY ENTRY WINDOW TITLE }
  1209.             CASE OPT OF
  1210.                 KEYF4:  WRITEWINDOW(JUSTC('Transfer funds',80));
  1211.                 KEYF5:  WRITEWINDOW(JUSTC(F5TRANS,80));
  1212.                 KEYF6:  WRITEWINDOW(JUSTC(F6TRANS,80));
  1213.                 KEYF7:  WRITEWINDOW(JUSTC('Miscellaneous debit',80));
  1214.                 KEYF8:  WRITEWINDOW(JUSTC('Miscellaneous credit',80));
  1215.             END;
  1216.             SHOWOPTIONS(#24+#25,'Select','','','F10','Accept','ESC','Abort');
  1217.             TEXTATTR:=MAINCOLOR;
  1218.             WITH ACSTATUS[ID] DO          { CHECK WHICH OPTIONS REQUIRED }
  1219.                 BEGIN
  1220.                     OPTCREDIT:=(OPT=KEYF4) OR
  1221.                                 ((OPT=KEYF5) AND (ACTYPE=CHECKING));
  1222.                     OPTCHECKNUM:=((OPT=KEYF5) AND (ACTYPE=CHECKING)) OR
  1223.                                  ((OPT=KEYF6) AND (ACTYPE=CARD));
  1224.                     OPTCHECKAC:=(OPT=KEYF6) AND (ACTYPE=CARD);
  1225.                     AC:=' ';
  1226.                     IF ACTYPE=CHECKING THEN
  1227.                         CN:=CHECKNUM
  1228.                     ELSE
  1229.                         CN:=0;
  1230.                 END;
  1231.             GOTOXY(TCOL,3); WRITE('Date');              { SET UP FIELDS }
  1232.             GOTOXY(FCOL,3); WRITE(#32,DATESTR(CURDATE));
  1233.             IF OPT<>KEYF4 THEN
  1234.                 BEGIN
  1235.                     GOTOXY(TCOL,5); WRITE('Detail');
  1236.                 END;
  1237.             GOTOXY(TCOL,7); WRITE('Amount');
  1238.             IF OPTCREDIT THEN
  1239.                 BEGIN
  1240.                     GOTOXY(TCOL,9); WRITE('Credit A/C');
  1241.                 END;
  1242.             IF OPTCHECKAC THEN
  1243.                 BEGIN
  1244.                     GOTOXY(TCOL,9); WRITE('Checking A/C');
  1245.                 END;
  1246.             IF OPTCHECKNUM THEN
  1247.                 WITH ACSTATUS[ID] DO
  1248.                     BEGIN
  1249.                         GOTOXY(TCOL,11); WRITE('Check number');
  1250.                         IF ACTYPE=CHECKING THEN
  1251.                             BEGIN
  1252.                                 GOTOXY(FCOL,11);
  1253.                                 WRITE(FORMAT(CHECKNUM,CHKFORMAT));
  1254.                             END;
  1255.                     END;
  1256.             FIELD:=0;               { SET STARTING FIELD }
  1257.             WITH NEWTRANS DO
  1258.                 REPEAT              { MAIN EDIT LOOP }
  1259.                     CASE FIELD OF
  1260.                         0:  BEGIN                   { EDIT DATE }
  1261.                                 GOTOXY(FCOL,3);
  1262.                                 WORDTODATE(DATE,D);
  1263.                                 REPEAT
  1264.                                     C:=EDITDATE(TRANSDATEEDIT,D);
  1265.                                     IF C='+' THEN
  1266.                                         ADJUSTDATE(D,1);
  1267.                                     IF C='-' THEN
  1268.                                         ADJUSTDATE(D,-1);
  1269.                                 UNTIL NOT(C IN ['+','-']);
  1270.                                 DATE:=DATETOWORD(D);
  1271.                             END;
  1272.                         1:  IF OPT<>KEYF4 THEN      { EDIT DETAIL }
  1273.                                 BEGIN
  1274.                                 GOTOXY(FCOL,5);
  1275.                                 IF (ACSTATUS[ID].ACTYPE=CHECKING) AND
  1276.                                         (OPT=KEYF5) THEN
  1277.                                     C:=EDITSTRING
  1278.                                         (ACNAMEEDIT,DETAIL,DETAILLEN-7)
  1279.                                 ELSE
  1280.                                     C:=EDITSTRING(ACNAMEEDIT,DETAIL,DETAILLEN);
  1281.                                 END;
  1282.                         2:  BEGIN                   { EDIT AMOUNT }
  1283.                                 GOTOXY(FCOL,7);
  1284.                                 C:=EDITINT(MONEYEDIT,AMOUNT,0,MAXMONEY);
  1285.                             END;
  1286.                         3:  BEGIN                   { EDIT AUX. ACCOUNT ID }
  1287.                                 GOTOXY(FCOL,9);
  1288.                                 REPEAT
  1289.                                     PREVAC:=AC;
  1290.                                     C:=EDITSTRING(ACREFEDIT,AC,1);
  1291.                                     VALIDAUXAC:=TRUE;
  1292.                                     IF AC[1]<>#32 THEN
  1293.                                         CASE ACSTATUS[AC[1]].ACTYPE OF
  1294.                                             UNUSED:
  1295.                                                 BEGIN
  1296.                                                     VALIDAUXAC:=FALSE;
  1297.                                                     DISPLAYERROR
  1298.                                                         ('Account not in use');
  1299.                                                     AC:=PREVAC;
  1300.                                                 END;
  1301.                                             SAVINGS,
  1302.                                             CARD:
  1303.                                                 IF OPTCHECKAC THEN
  1304.                                                     BEGIN
  1305.                                                         VALIDAUXAC:=FALSE;
  1306.                                                         DISPLAYERROR
  1307.                                                     ('Not a checking account');
  1308.                                                         AC:=PREVAC;
  1309.                                                     END;
  1310.                                         END;  { CASE }
  1311.                                     IF AC[1]=ID THEN
  1312.                                         BEGIN
  1313.                                             VALIDAUXAC:=FALSE;
  1314.                                             DISPLAYERROR
  1315.                                         ('Cannot transfer to same account');
  1316.                                             AC:=PREVAC;
  1317.                                         END;
  1318.                                 UNTIL VALIDAUXAC;
  1319.                                 IF OPTCHECKAC AND (PREVAC[1]<>AC[1]) THEN
  1320.                                     BEGIN
  1321.                                         GOTOXY(FCOL,11);
  1322.                                         IF AC[1]<>#32 THEN
  1323.                                             BEGIN
  1324.                                                 CN:=ACSTATUS[AC[1]].CHECKNUM;
  1325.                                                 WRITE(FORMAT(CN,CHKFORMAT));
  1326.                                                 DETAIL:='PAYMENT: '+AC[1]+'-'+
  1327.                                                     FORMAT(CN,CHKFORMAT);
  1328.                                                 GOTOXY(FCOL,5);
  1329.                                                 WRITE(PADR(DETAIL,DETAILLEN));
  1330.                                             END
  1331.                                         ELSE
  1332.                                             BEGIN
  1333.                                                 WRITE('':6);
  1334.                                                 CN:=0;
  1335.                                                 DETAIL:='';
  1336.                                                 GOTOXY(FCOL,5); CLREOL;
  1337.                                             END;
  1338.                                     END;
  1339.                             END;
  1340.                         4:  BEGIN                   { EDIT CHECK NUMBER }
  1341.                                 GOTOXY(FCOL,11);
  1342.                                 IF CN<>0 THEN
  1343.                                     BEGIN
  1344.                                         C:=EDITINT(CHECKNUMEDIT,
  1345.                                                     CN,1,MAXCHECKNUM);
  1346.                                         IF (AC[1]<>#32) AND (OPT<>KEYF5) THEN
  1347.                                             BEGIN
  1348.                                                 DETAIL:='PAYMENT: '+AC[1]+'-'+
  1349.                                                     FORMAT(CN,CHKFORMAT);
  1350.                                                 GOTOXY(FCOL,5);
  1351.                                                 WRITE(PADR(DETAIL,DETAILLEN));
  1352.                                             END;
  1353.                                     END;
  1354.                             END;
  1355.                      END;  { CASE FIELD }
  1356.                     CASE C OF       { MOVE TO NEXT FIELD, AS REQUIRED }
  1357.                         KEYUP,
  1358.                         KEYSTAB:
  1359.                             IF FIELD=0 THEN
  1360.                                 IF OPTCHECKNUM THEN
  1361.                                     FIELD:=4
  1362.                                 ELSE
  1363.                                     IF OPTCREDIT THEN
  1364.                                         FIELD:=3
  1365.                                     ELSE
  1366.                                         FIELD:=2
  1367.                             ELSE
  1368.                                 DEC(FIELD);
  1369.                         CR,
  1370.                         KEYDOWN,
  1371.                         HT:
  1372.                             BEGIN
  1373.                                 INC(FIELD);
  1374.                                 IF (FIELD=3) AND
  1375.                                     NOT(OPTCREDIT OR OPTCHECKAC) THEN
  1376.                                     FIELD:=0;
  1377.                                 IF (FIELD=4) AND NOT(OPTCHECKNUM) THEN
  1378.                                     FIELD:=0;
  1379.                             END;
  1380.                     END;  { CASE C }
  1381.                     VALIDAUXAC:=(OPT<>KEYF4) OR (AC[1]<>#32) OR (C=ESC);
  1382.                     IF (C=KEYF10) AND NOT(VALIDAUXAC) THEN
  1383.                         BEGIN
  1384.                             DISPLAYERROR('Transfer account not specified');
  1385.                             FIELD:=3;
  1386.                         END;
  1387.                 UNTIL (C IN [KEYF10,ESC]) AND VALIDAUXAC;
  1388.             IF C=KEYF10 THEN                { PROCESS TRANSACTION }
  1389.                 BEGIN
  1390.                     WORDTODATE(NEWTRANS.DATE,CURDATE);
  1391.                     WITH ACSTATUS[ID] DO    { ADD CHECK NUMBER, UPDATE NEXT }
  1392.                         IF (ACTYPE=CHECKING) AND (OPT=KEYF5) THEN
  1393.                             BEGIN
  1394.                                 NEWTRANS.DETAIL:=FORMAT(CN,CHKFORMAT)+' '+
  1395.                                                     NEWTRANS.DETAIL;
  1396.                                 CHECKNUM:=CN+1;
  1397.                             END;
  1398.                     IF OPT=KEYF4 THEN       { ADD DESCRIPTION FOR TRANSFER }
  1399.                         NEWTRANS.DETAIL:='Transfer to A/C '+AC[1];
  1400.                     IF OPT IN [KEYF4,KEYF5,KEYF7] THEN  { NEGATE IF DEBIT }
  1401.                         NEWTRANS.AMOUNT:=-NEWTRANS.AMOUNT;
  1402.                     ADDTRANS(ACSTATUS[ID],NEWTRANS);
  1403.                     IF AC[1]<>#32 THEN      { CHECK FOR AUX. ACCOUNT ENTRY }
  1404.                         BEGIN
  1405.                             {$I-}
  1406.                             CLOSE(TRANSFILE);
  1407.                             DISKCHECK(IORESULT);    { SWITCH TO AUX. }
  1408.                             ASSIGN(TRANSFILE,DATAFILEPATH+TRANSFN+AC[1]+FNEXT);
  1409.                             RESET(TRANSFILE); DISKCHECK(IORESULT);
  1410.                             WITH NEWTRANS DO
  1411.                                 BEGIN
  1412.                                     AMOUNT:=-AMOUNT;    { SWAP DR/CR ENTRY }
  1413.                                     IF OPTCREDIT THEN   { CHANGE DETAIL FIELD }
  1414.                                         IF OPT=KEYF4 THEN
  1415.                                             DETAIL:='Transfer from A/C '+ID
  1416.                                         ELSE
  1417.                                             DETAIL:='Transfer: '+ID+'-'+
  1418.                                                         FORMAT(CN,CHKFORMAT)
  1419.                                     ELSE
  1420.                                         WITH ACSTATUS[AC[1]] DO
  1421.                                             BEGIN
  1422.                                                 DETAIL:=FORMAT(CN,CHKFORMAT)+
  1423.                                                         ' Account '+ID;
  1424.                                                 CHECKNUM:=CN+1;
  1425.                                             END;
  1426.                                 END;  { WITH NEWTRANS }
  1427.                             ADDTRANS(ACSTATUS[AC[1]],NEWTRANS);
  1428.                                                     { ADD AUX. TRANSACTION }
  1429.                             CLOSE(TRANSFILE);
  1430.                             DISKCHECK(IORESULT);    { SWITCH BACK ACCOUNT }
  1431.                             ASSIGN(TRANSFILE,DATAFILEPATH+TRANSFN+ID+FNEXT);
  1432.                             RESET(TRANSFILE); DISKCHECK(IORESULT);
  1433.                             {$I+}
  1434.                         END;
  1435.                     ENTERTRANS:=TRUE;
  1436.                 END
  1437.             ELSE
  1438.                 ENTERTRANS:=FALSE;
  1439.             CLOSEWINDOW(8);         { RESTORE DISPLAY }
  1440.         END;  { ENTERTRANS }
  1441.  
  1442.  
  1443.     PROCEDURE PRINTTRANS;       { PRINT TRANSACTIONS }
  1444.  
  1445.         VAR
  1446.             T:  TRANSREC;           { TRANSACTION STORAGE }
  1447.             B:  LONGINT;            { BALANCE }
  1448.             I:  LONGINT;            { TRANSACTION RECORD NUMBER }
  1449.             PN: WORD;               { PAGE NUMBER }
  1450.             LC: BYTE;               { LINE COUNTER }
  1451.  
  1452.  
  1453.         BEGIN
  1454.             MARKTRANS(TRUE);
  1455.             IF GETYESNO('Print from current transaction to end',
  1456.                             'Are you sure?') THEN
  1457.                 BEGIN
  1458.                     OPENWINDOW(3);                  { SET UP }
  1459.                     WRITEWINDOW(JUSTC('Printing - Please wait',38));
  1460.                     GOTOXY(1,2);
  1461.                     WRITEWINDOW(JUSTC('Press ESC to abort',38));
  1462.                     I:=TOPTRANS+CRSROFFSET;
  1463.                     READTRANS(I,T);
  1464.                     B:=T.BALANCE-T.AMOUNT;
  1465.                     PN:=1; LC:=0;
  1466.                     WHILE (I<FILESIZE(TRANSFILE)) DO
  1467.                         BEGIN               { FOR EACH TRANSACTION }
  1468.                             READTRANS(I,T);
  1469.                             IF LC=0 THEN    { PRINT PAGE HEADING IF NECESSARY }
  1470.                                 WITH ACSTATUS[ID] DO
  1471.                                     BEGIN
  1472.                                         WRITELN(PRN);
  1473.                                         WRITELN(PRN,ID+': '+PADR(NAME,68),
  1474.                                                 'Page ',PN:3);
  1475.                                         WRITELN(PRN,DUPLCHAR('-',79));
  1476.                                         WRITELN(PRN);
  1477.                                         WRITELN(PRN,'   Date    ',
  1478.                                             'Detail              ',
  1479.                                             'Debit':14,' ','Credit':14,' ',
  1480.                                             'Balance':14,'  Rec');
  1481.                                         WRITELN(PRN);
  1482.                                         IF T.RECON<>BAL THEN
  1483.                                             BEGIN
  1484.                                                 WRITELN(PRN,'':11,
  1485.                                                     PADR('Balance b/f',51),
  1486.                                                     FORMAT(B/100,MNYZFORMAT));
  1487.                                                 WRITELN(PRN);
  1488.                                                 LC:=8;
  1489.                                             END
  1490.                                         ELSE
  1491.                                             LC:=6;
  1492.                                         INC(PN);
  1493.                                     END;
  1494.                                 WRITELN(PRN,TRANSTOSTR(T));
  1495.                                                         { PRINT TRANSACTION }
  1496.                                 INC(LC);
  1497.                                 IF KEYPRESSED THEN      { CHECK FOR USR ABORT }
  1498.                                     IF READKEY=ESC THEN
  1499.                                         BEGIN
  1500.                                             WRITELN(PRN);
  1501.                                             WRITELN(PRN,'Aborted by user');
  1502.                                             WRITE(PRN,FF);
  1503.                                             CLOSEWINDOW(3);
  1504.                                             EXIT;
  1505.                                         END;
  1506.                                 IF (LC=53) AND
  1507.                                         (I<(FILESIZE(TRANSFILE)-1)) THEN
  1508.                                     BEGIN
  1509.                                         B:=T.BALANCE;
  1510.                                         WRITELN(PRN);
  1511.                                         WRITELN(PRN,'':11,
  1512.                                                 PADR('Balance c/f',51),
  1513.                                                 FORMAT(B/100,MNYZFORMAT),FF);
  1514.                                         LC:=0;
  1515.                                     END;
  1516.                                 INC(I);
  1517.                         END;
  1518.                     IF LC<>0 THEN
  1519.                         WRITE(PRN,FF);
  1520.                     CLOSEWINDOW(3);         { RESTORE DISPLAY }
  1521.                 END;
  1522.             MARKTRANS(FALSE);
  1523.         END;  { PRINTTRANS }
  1524.  
  1525.  
  1526.     { PURGE TRANSACTIONS FROM FILE AND UPDATE B/F BALANCE.
  1527.       RETURNS TRUE IF PURGE CARRIED OUT, OTHERWISE RETURNS FALSE. }
  1528.  
  1529.     FUNCTION PURGETRANS: BOOLEAN;
  1530.  
  1531.         VAR
  1532.             B,T:    TRANSREC;
  1533.             I,J:    LONGINT;
  1534.  
  1535.         BEGIN
  1536.             PURGETRANS:=FALSE;
  1537.             I:=TOPTRANS+CRSROFFSET;
  1538.             IF I=0 THEN
  1539.                 BEGIN
  1540.                     DISPLAYERROR('No transactions to purge');
  1541.                     EXIT;
  1542.                 END;
  1543.             REPEAT
  1544.                 READTRANS(I,T);
  1545.                 IF T.RECON=UNREC THEN
  1546.                     BEGIN
  1547.                         DISPLAYERROR('Cannot purge - Unreconciled entries');
  1548.                         EXIT;
  1549.                     END;
  1550.                 DEC(I);
  1551.             UNTIL I=0;
  1552.             MARKTRANS(TRUE);
  1553.             WRITE(BEL,BEL);
  1554.             IF GETYESNO('Purge to current transaction','Are you sure?') THEN
  1555.                 BEGIN
  1556.                     I:=0;
  1557.                     J:=TOPTRANS+CRSROFFSET;
  1558.                     READTRANS(I,B);
  1559.                     READTRANS(J,T);
  1560.                     B.AMOUNT:=T.BALANCE;
  1561.                     B.BALANCE:=B.AMOUNT;
  1562.                     WRITETRANS(I,B);
  1563.                     INC(I); INC(J);
  1564.                     WHILE (J<FILESIZE(TRANSFILE)) DO
  1565.                         BEGIN
  1566.                             READTRANS(J,T);
  1567.                             WRITETRANS(I,T);
  1568.                             INC(I); INC(J);
  1569.                         END;
  1570.                     SEEK(TRANSFILE,I); DISKCHECK(IORESULT);
  1571.                     TRUNCATE(TRANSFILE); DISKCHECK(IORESULT);
  1572.                     PURGETRANS:=TRUE;
  1573.                 END;
  1574.             MARKTRANS(FALSE);
  1575.         END;  { PURGETRANS }
  1576.  
  1577.  
  1578.     BEGIN  { ACCESSACCOUNT }
  1579.         SAVEDHC:=HELPCONTEXT;
  1580.         GETTODAY(CURDATE);
  1581.         SELECTWINDOW(1);            { SET UP DISPLAY }
  1582.         CLRSCR;
  1583.         WRITE(PADR(ID+': '+ACSTATUS[ID].NAME,70),DATESTR(CURDATE));
  1584.         SELECTWINDOW(2);
  1585.         CLRSCR;
  1586.                         { OPEN APPROPRIATE FILES }
  1587.         ASSIGN(TRANSFILE,DATAFILEPATH+TRANSFN+ID+FNEXT);
  1588.         ASSIGN(AUTOFILE,DATAFILEPATH+AUTOFN+ID+FNEXT);
  1589.         {$I-}
  1590.         RESET(TRANSFILE); DISKCHECK(IORESULT);
  1591.         RESET(AUTOFILE); DISKCHECK(IORESULT);
  1592.         {$I+}
  1593.         CASE ACSTATUS[ID].ACTYPE OF     { SET NAMES OF MAIN DR/CR OPTIONS }
  1594.             CHECKING:   BEGIN
  1595.                             F5TRANS:='Check'; F6TRANS:='Deposit';
  1596.                         END;
  1597.             SAVINGS:    BEGIN
  1598.                             F5TRANS:='Withdrawal'; F6TRANS:='Deposit';
  1599.                         END;
  1600.             CARD:       BEGIN
  1601.                             F5TRANS:='Purchase'; F6TRANS:='Payment';
  1602.                         END;
  1603.         END;  { CASE }
  1604.         TEXTATTR:=HIGHCOLOR; WRITE('F2');
  1605.         TEXTATTR:=MAINCOLOR; WRITELN(' Purge');
  1606.         TEXTATTR:=HIGHCOLOR; WRITE('F3');
  1607.         TEXTATTR:=MAINCOLOR; WRITELN(' Auto entries');
  1608.         TEXTATTR:=HIGHCOLOR; WRITE('F4');
  1609.         TEXTATTR:=MAINCOLOR; WRITELN(' Transfer');
  1610.         TEXTATTR:=HIGHCOLOR; WRITE('F9');
  1611.         TEXTATTR:=MAINCOLOR; WRITELN(' Print');
  1612.         GOTOXY(25,1);
  1613.         TEXTATTR:=HIGHCOLOR; WRITE('F5');
  1614.         TEXTATTR:=MAINCOLOR; WRITE(#32,F5TRANS);
  1615.         GOTOXY(25,2);
  1616.         TEXTATTR:=HIGHCOLOR; WRITE('F6');
  1617.         TEXTATTR:=MAINCOLOR; WRITE(#32,F6TRANS);
  1618.         GOTOXY(25,3);
  1619.         TEXTATTR:=HIGHCOLOR; WRITE('F7');
  1620.         TEXTATTR:=MAINCOLOR; WRITE(' Misc. debit');
  1621.         GOTOXY(25,4);
  1622.         TEXTATTR:=HIGHCOLOR; WRITE('F8');
  1623.         TEXTATTR:=MAINCOLOR; WRITE(' Misc. credit');
  1624.         GOTOXY(1,7);
  1625.         TEXTATTR:=TITLECOLOR;
  1626.         WRITE('   Date    ','Detail              ','Debit':14,' ',
  1627.               'Credit':14,' ','Balance':14,'  Rec');
  1628.         TEXTATTR:=MAINCOLOR;
  1629.         SHOWBAL;
  1630.         OPENWINDOW(6);          { WINDOW FOR VIEWING TRANSACTIONS }
  1631.         LASTTRANS;
  1632.         WITH ACSTATUS[ID] DO
  1633.             BEGIN
  1634.                 REPEAT          { MAIN LOOP }
  1635.                     SHOWOPTIONS(#24+#25,'Select','Enter','Rec',
  1636.                                 '+ -','Next unrec','ESC','Main menu');
  1637.                     MARKTRANS(TRUE);
  1638.                     OPT:=READKEY;
  1639.                     MARKTRANS(FALSE);
  1640.                     CASE OPT OF
  1641.                         KEYUP:
  1642.                             B:=PREVTRANS;
  1643.                         KEYDOWN:
  1644.                             B:=NEXTTRANS;
  1645.                         KEYPGUP:
  1646.                             IF TOPTRANS+CRSROFFSET=0 THEN
  1647.                                 WRITE(BEL)
  1648.                             ELSE
  1649.                                 BEGIN
  1650.                                     TOPTRANS:=TOPTRANS-11;
  1651.                                     IF TOPTRANS<0 THEN
  1652.                                         BEGIN
  1653.                                             TOPTRANS:=0;
  1654.                                             CRSROFFSET:=0;
  1655.                                         END;
  1656.                                     TRANSPAGE;
  1657.                                 END;
  1658.                         KEYPGDN:
  1659.                             IF TOPTRANS+CRSROFFSET+1=FILESIZE(TRANSFILE) THEN
  1660.                                 WRITE(BEL)
  1661.                             ELSE
  1662.                                 BEGIN
  1663.                                     TOPTRANS:=TOPTRANS+11;
  1664.                                     IF TOPTRANS+11>=FILESIZE(TRANSFILE) THEN
  1665.                                         BEGIN
  1666.                                             TOPTRANS:=FILESIZE(TRANSFILE)-12;
  1667.                                             IF TOPTRANS<0 THEN
  1668.                                                 BEGIN
  1669.                                                     TOPTRANS:=0;
  1670.                                                     CRSROFFSET:=
  1671.                                                         FILESIZE(TRANSFILE)-1;
  1672.                                                 END
  1673.                                             ELSE
  1674.                                                 CRSROFFSET:=11;
  1675.                                         END;
  1676.                                     TRANSPAGE;
  1677.                                 END;
  1678.                         KEYHOME:  FIRSTTRANS;
  1679.                         KEYEND:   LASTTRANS;
  1680.                         HT,'+':
  1681.                             REPEAT
  1682.                                 B:=NEXTTRANS;
  1683.                                 READTRANS(TOPTRANS+CRSROFFSET,TRANS);
  1684.                             UNTIL NOT(B) OR (TRANS.RECON=UNREC);
  1685.                         KEYSTAB,'-':
  1686.                             REPEAT
  1687.                                 B:=PREVTRANS;
  1688.                                 READTRANS(TOPTRANS+CRSROFFSET,TRANS);
  1689.                             UNTIL NOT(B) OR (TRANS.RECON=UNREC);
  1690.                         CR: BEGIN
  1691.                                 READTRANS(TOPTRANS+CRSROFFSET,TRANS);
  1692.                                 WITH TRANS DO
  1693.                                     CASE RECON OF
  1694.                                         UNREC:  BEGIN
  1695.                                                     RECON:=REC;
  1696.                                                     UNRECBAL:=UNRECBAL-AMOUNT;
  1697.                                                     RECBAL:=RECBAL+AMOUNT;
  1698.                                                 END;
  1699.                                         REC:    BEGIN
  1700.                                                     RECON:=UNREC;
  1701.                                                     RECBAL:=RECBAL-AMOUNT;
  1702.                                                     UNRECBAL:=UNRECBAL+AMOUNT;
  1703.                                                 END;
  1704.                                         BAL:    DISPLAYERROR
  1705.                                             ('Cannot reconcile b/f balance');
  1706.                                     END;
  1707.                                 WRITETRANS(TOPTRANS+CRSROFFSET,TRANS);
  1708.                                 GOTOXY(1,CRSROFFSET+1);
  1709.                                 WRITEWINDOW(TRANSTOSTR(TRANS));
  1710.                                 SHOWBAL;
  1711.                             END;
  1712.                         KEYF2:  IF PURGETRANS THEN FIRSTTRANS;
  1713.                         KEYF3:
  1714.                             BEGIN
  1715.                                 HELPCONTEXT:=7;
  1716.                                 AUTOTRANS;
  1717.                             END;
  1718.                         KEYF4,KEYF5,KEYF6,KEYF7,KEYF8:
  1719.                             BEGIN
  1720.                                 CASE OPT OF
  1721.                                     KEYF4:  HELPCONTEXT:=8;
  1722.                                     KEYF5:  CASE ACTYPE OF
  1723.                                                 CHECKING: HELPCONTEXT:=9;
  1724.                                                 SAVINGS:  HELPCONTEXT:=10;
  1725.                                                 CARD:     HELPCONTEXT:=11;
  1726.                                             END;
  1727.                                     KEYF6:  IF ACTYPE=CARD THEN
  1728.                                                 HELPCONTEXT:=13
  1729.                                             ELSE
  1730.                                                 HELPCONTEXT:=12;
  1731.                                     KEYF7:  HELPCONTEXT:=14;
  1732.                                     KEYF8:  HELPCONTEXT:=15;
  1733.                                 END;  { CASE OPT }
  1734.                                 IF ENTERTRANS THEN
  1735.                                     BEGIN
  1736.                                         SHOWBAL;
  1737.                                         LASTTRANS;
  1738.                                     END;
  1739.                             END;
  1740.                         KEYF9:  PRINTTRANS;
  1741.                     END;  { CASE OPT }
  1742.                     HELPCONTEXT:=SAVEDHC;
  1743.                 UNTIL OPT IN [ESC,KEYCPGUP,KEYCPGDN,KEYCHOME,KEYCEND];
  1744.             END;  { WITH ACSTATUS[ID] }
  1745.         ACCESSACCOUNT:=OPT;                     { RETURN TERMINATING KEY }
  1746.         CLOSEWINDOW(6);                         { CLEAR DISPLAY }
  1747.         {$I-}
  1748.         CLOSE(TRANSFILE); DISKCHECK(IORESULT);  { CLOSE ACCOUNT FILES }
  1749.         CLOSE(AUTOFILE); DISKCHECK(IORESULT);
  1750.         {$I+}
  1751.         UPDATEACSTATFILE;
  1752.     END;  { ACCESSACCOUNT }
  1753.  
  1754.  
  1755. (*
  1756.     DISPLAY SUMMARY OF ACCOUNT BALANCES.
  1757. *)
  1758.  
  1759. PROCEDURE ACCOUNTSUMMARY;
  1760.  
  1761.     VAR
  1762.         BAL:    ARRAY[ACCOUNTTYPE] OF LONGINT;
  1763.         T:      ACCOUNTTYPE;
  1764.         DT:     DATEREC;
  1765.         C:      CHAR;
  1766.  
  1767.     BEGIN
  1768.         CLRSCR;
  1769.         SHOWOPTIONS('','','F9','Print','','','ESC','Main menu');
  1770.         GOTOXY(1,3);
  1771.         WRITEWINDOW(JUSTC('SUMMARY OF ACCOUNTS',80));
  1772.         BAL[CHECKING]:=0;
  1773.         BAL[SAVINGS]:=0;
  1774.         BAL[CARD]:=0;
  1775.         FOR C:='A' TO 'Z' DO
  1776.             WITH ACSTATUS[C] DO
  1777.                 BAL[ACTYPE]:=BAL[ACTYPE]+RECBAL+UNRECBAL;
  1778.         GOTOXY(1,8);
  1779.         WRITELN('':25,'Checking accounts',
  1780.                     FORMAT(BAL[CHECKING]/100,MNYZFORMAT));
  1781.         WRITELN('':25,'Savings accounts ',
  1782.                     FORMAT(BAL[SAVINGS]/100,MNYZFORMAT));
  1783.         WRITELN('':25,'Credit accounts  ',
  1784.                     FORMAT(BAL[CARD]/100,MNYZFORMAT));
  1785.         WRITELN('':42,DUPLCHAR(#196,14));
  1786.         WRITELN('':25,'Total            ',
  1787.                 FORMAT((BAL[CHECKING]+BAL[SAVINGS]+BAL[CARD])/100,MNYDFORMAT));
  1788.         WRITELN('':42,DUPLCHAR(#205,14));
  1789.         REPEAT
  1790.             C:=READKEY;
  1791.             IF C=KEYF9 THEN
  1792.                 IF GETYESNO('Print detailed summary','Are you sure?') THEN
  1793.                     BEGIN
  1794.                         GETTODAY(DT);
  1795.                         WRITELN(PRN);
  1796.                         WRITELN(PRN,PADR('ACCOUNTS SUMMARY',70),DATESTR(DT));
  1797.                         WRITELN(PRN,DUPLCHAR('-',79));
  1798.                         WRITELN(PRN,DUPLCHAR(LF,5));
  1799.                         FOR T:=CHECKING TO CARD DO
  1800.                             BEGIN
  1801.                                 CASE T OF
  1802.                                     CHECKING:
  1803.                                         WRITELN(PRN,'Checking accounts',LF);
  1804.                                     SAVINGS:
  1805.                                         WRITELN(PRN,'Savings accounts',LF);
  1806.                                     CARD:
  1807.                                         WRITELN(PRN,'Credit accounts',LF);
  1808.                                 END;
  1809.                                 FOR C:='A' TO 'Z' DO
  1810.                                     WITH ACSTATUS[C] DO
  1811.                                         IF ACTYPE=T THEN
  1812.                                             WRITELN(PRN,
  1813.                                                     C:10,'   ',PADR(NAME,33),
  1814.                                                     FORMAT((RECBAL+UNRECBAL)/100,
  1815.                                                             MNYFORMAT));
  1816.                                             WRITELN(PRN,'':46,DUPLCHAR('-',14),
  1817.                                                     FORMAT(BAL[T]/100,
  1818.                                                             MNYZFORMAT),LF,LF);
  1819.                             END;
  1820.                         WRITELN(PRN,LF,'':60,DUPLCHAR('-',14));
  1821.                         WRITELN(PRN,'':60,
  1822.                             FORMAT((BAL[CHECKING]+BAL[SAVINGS]+BAL[CARD])/100,
  1823.                                     MNYDFORMAT));
  1824.                         WRITE(PRN,'':60,DUPLCHAR('=',14),FF);
  1825.                     END;
  1826.         UNTIL C=ESC;
  1827.     END;  { ACCOUNTSUMMARY }
  1828.  
  1829.  
  1830.  
  1831. (*
  1832.     MAIN MENU OPTION TO SET-UP ACCOUNTS AND MISCELLANEOUS DATA.
  1833. *)
  1834.  
  1835. PROCEDURE ACCOUNTSETUP;
  1836.  
  1837.     VAR
  1838.         CURDATE:    DATEREC;
  1839.         C:          CHAR;
  1840.  
  1841.     FUNCTION ACTYPETOSTR(T: ACCOUNTTYPE): STRING;   { CONVERT TYPE TO STRING }
  1842.  
  1843.         BEGIN
  1844.             CASE T OF
  1845.                 CHECKING:   ACTYPETOSTR:='Checking   ';
  1846.                 SAVINGS:    ACTYPETOSTR:='Savings    ';
  1847.                 CARD:       ACTYPETOSTR:='Credit/Loan';
  1848.                 UNUSED:     ACTYPETOSTR:='DELETE     ';
  1849.             END;
  1850.         END;  { ACTYPETOSTR }
  1851.  
  1852.  
  1853.     PROCEDURE EDITACCOUNTSTAT(ID: CHAR);    { CREATE/EDIT ACCOUNT DETAILS }
  1854.  
  1855.         CONST
  1856.             TCOL  = 12;
  1857.             FCOL  = 35;
  1858.  
  1859.         VAR
  1860.             STAT:   ACCOUNTREC;
  1861.             T:      TRANSREC;
  1862.             FIELD:  BYTE;
  1863.             R:      BYTE;
  1864.             C:      CHAR;
  1865.             S:      STRING[11];
  1866.             NEWAC:  BOOLEAN;
  1867.  
  1868.         BEGIN
  1869.             STAT:=ACSTATUS[ID];
  1870.             ASSIGN(TRANSFILE,DATAFILEPATH+TRANSFN+ID+FNEXT);
  1871.             ASSIGN(AUTOFILE,DATAFILEPATH+AUTOFN+ID+FNEXT);
  1872.             NEWAC:=(STAT.ACTYPE=UNUSED);
  1873.             IF NEWAC THEN       { CREATE A NEW ACCOUNT }
  1874.                 BEGIN
  1875.                     IF GETYESNO('Account '+ID+' not in use at present',
  1876.                                 'Create this account?') THEN
  1877.                         BEGIN
  1878.                             STAT.ACTYPE:=CHECKING;
  1879.                             STAT.NAME:='Account name';
  1880.                         END
  1881.                     ELSE
  1882.                         EXIT;
  1883.                 END;
  1884.             CLRSCR;             { DISPLAY CURRENT DETAILS }
  1885.             WRITEWINDOW(JUSTC('Account '+ID,80));
  1886.             SHOWOPTIONS(#24+#25,'Select','','','F10','Accept','ESC','Abort');
  1887.             WITH STAT DO
  1888.                 BEGIN
  1889.                     GOTOXY(TCOL,5);
  1890.                     WRITE('Account type           ',ACTYPETOSTR(ACTYPE));
  1891.                     GOTOXY(TCOL,7);
  1892.                     WRITE('Name                   ',NAME);
  1893.                     GOTOXY(TCOL,9);
  1894.                     WRITE('Debit default          ',DRDEFAULT);
  1895.                     GOTOXY(TCOL,11);
  1896.                     WRITE('Credit default         ',CRDEFAULT);
  1897.                     GOTOXY(TCOL,13);
  1898.                     WRITE('Next check no.         ',
  1899.                                 FORMAT(CHECKNUM,CHKFORMAT));
  1900.                     FIELD:=0;
  1901.                     REPEAT
  1902.                         CASE FIELD OF
  1903.                             0:  BEGIN           { EDIT ACCOUNT TYPE }
  1904.                                     GOTOXY(FCOL,5);
  1905.                                     S:=ACTYPETOSTR(ACTYPE);
  1906.                                     C:=EDITSTRING(ACTYPEEDIT,S,11);
  1907.                                     IF C=#32 THEN
  1908.                                         IF ACTYPE=CARD THEN
  1909.                                             IF NEWAC THEN
  1910.                                                 ACTYPE:=CHECKING
  1911.                                             ELSE
  1912.                                                 ACTYPE:=UNUSED
  1913.                                         ELSE
  1914.                                             INC(ACTYPE);
  1915.                                 END;
  1916.                             1:  BEGIN           { EDIT ACCOUNT NAME }
  1917.                                     GOTOXY(FCOL,7);
  1918.                                     C:=EDITSTRING(ACNAMEEDIT,NAME,ACNAMELEN);
  1919.                                 END;
  1920.                             2:  BEGIN                 { EDIT DEBIT TEXT }
  1921.                                     GOTOXY(FCOL,9);
  1922.                                     C:=EDITSTRING(ACNAMEEDIT,DRDEFAULT,
  1923.                                                     DETAILLEN);
  1924.                                 END;
  1925.                             3:  BEGIN                 { EDIT CREDIT TEXT }
  1926.                                     GOTOXY(FCOL,11);
  1927.                                     C:=EDITSTRING(ACNAMEEDIT,CRDEFAULT,
  1928.                                                     DETAILLEN);
  1929.                                 END;
  1930.                             4:  BEGIN                 { EDIT CHECK NUMBER }
  1931.                                     GOTOXY(FCOL,13);
  1932.                                     C:=EDITINT(CHECKNUMEDIT,CHECKNUM,
  1933.                                                     1,MAXCHECKNUM);
  1934.                                 END;
  1935.                         END;  { CASE FIELD }
  1936.                         CASE C OF               { MOVE TO SELECTED FIELD }
  1937.                             KEYUP,KEYSTAB:
  1938.                                 IF FIELD=0 THEN FIELD:=4 ELSE DEC(FIELD);
  1939.                             KEYDOWN,HT,CR:
  1940.                                 IF FIELD=4 THEN FIELD:=0 ELSE INC(FIELD);
  1941.                         END;
  1942.                         IF C=KEYF10 THEN
  1943.                             IF (ACTYPE=UNUSED) AND
  1944.                                 (ACSTATUS[ID].ACTYPE<>UNUSED) THEN
  1945.                                 IF (RECBAL=0) AND (UNRECBAL=0) THEN
  1946.                                     { ALLOW DEL IF ZERO BAL & ALL RECONCILED }
  1947.                                     BEGIN
  1948.                                         WRITE(BEL,BEL);
  1949.                                         IF GETYESNO('Delete '+NAME,
  1950.                                                     'Are you sure?') THEN
  1951.                                             BEGIN
  1952.                                                 NAME:='';
  1953.                                                 RECBAL:=0;
  1954.                                                 UNRECBAL:=0;
  1955.                                                 DRDEFAULT:='';
  1956.                                                 CRDEFAULT:='';
  1957.                                                 CHECKNUM:=1;
  1958.                                                 {$I-}
  1959.                                                 ERASE(TRANSFILE);
  1960.                                                 R:=IORESULT;
  1961.                                                 IF R<>2 THEN
  1962.                                                     DISKCHECK(R);
  1963.                                                 ERASE(AUTOFILE);
  1964.                                                 R:=IORESULT;
  1965.                                                 IF R<>2 THEN
  1966.                                                     DISKCHECK(R);
  1967.                                                 {$I+}
  1968.                                             END
  1969.                                         ELSE
  1970.                                             C:=NUL;
  1971.                                     END
  1972.                                 ELSE
  1973.                                     BEGIN
  1974.                                         IF UNRECBAL<>0 THEN
  1975.                                             DISPLAYERROR
  1976.                                     ('Cannot delete - Unreconciled entries')
  1977.                                         ELSE
  1978.                                             DISPLAYERROR
  1979.                                     ('Cannot delete - Balance is not zero');
  1980.                                         C:=NUL;
  1981.                                     END;
  1982.                     UNTIL C IN [KEYF10,ESC];    { RPT UNTIL ACCEPT OR ABORT }
  1983.                 END;  { WITH STAT }
  1984.             IF C=KEYF10 THEN
  1985.                 BEGIN
  1986.                     ACSTATUS[ID]:=STAT; { IF CHANGES ACCEPTED, UPDATE AC REC. }
  1987.                     IF NEWAC THEN       { IF NEW ACCOUNT, CREATE FILES }
  1988.                         BEGIN
  1989.                             {$I-}
  1990.                             REWRITE(TRANSFILE); DISKCHECK(IORESULT);
  1991.                             WITH T DO
  1992.                                 BEGIN
  1993.                                     DATE:=DATETOWORD(CURDATE);
  1994.                                     AMOUNT:=0;
  1995.                                     BALANCE:=0;
  1996.                                     DETAIL:='Balance b/f';
  1997.                                     RECON:=BAL;
  1998.                                 END;
  1999.                             WRITETRANS(0,T);
  2000.                             CLOSE(TRANSFILE); DISKCHECK(IORESULT);
  2001.                             REWRITE(AUTOFILE); DISKCHECK(IORESULT);
  2002.                             CLOSE(AUTOFILE); DISKCHECK(IORESULT);
  2003.                             {$I+}
  2004.                         END;
  2005.                 END;
  2006.         END;  { EDITACCOUNTSTAT }
  2007.  
  2008.  
  2009.     BEGIN  { ACCOUNTSETUP }
  2010.         GETTODAY(CURDATE);
  2011.         SELECTWINDOW(1);            { DISPLAY OPTIONS }
  2012.         CLRSCR;
  2013.         WRITE(PADR('ACCOUNT MAINTENANCE',70),DATESTR(CURDATE));
  2014.         REPEAT
  2015.             SELECTWINDOW(2);
  2016.             LISTACCOUNTS;
  2017.             SHOWOPTIONS('','','A-Z','Select','','','ESC','Main menu');
  2018.             C:=UPCASE(READKEY);     { GET CHOICE, ACT AS REQUIRED }
  2019.             PUSHHELPCONTEXT(5);
  2020.             IF C IN ['A'..'Z'] THEN
  2021.                 EDITACCOUNTSTAT(C);
  2022.             POPHELPCONTEXT;
  2023.         UNTIL C=ESC;
  2024.         UPDATEACSTATFILE;
  2025.     END;  { ACCOUNTSETUP }
  2026.  
  2027.  
  2028.  
  2029. (*
  2030.     PROCESS AUTOMATIC TRANSACTION ENTRIES.
  2031. *)
  2032.  
  2033. PROCEDURE PROCESSAUTOTRANS;
  2034.  
  2035.     VAR
  2036.         T:      TRANSREC;
  2037.         ATR:    AUTOREC;
  2038.         DT:     DATEREC;
  2039.         D:      WORD;
  2040.         I:      LONGINT;
  2041.         C,CC:   CHAR;
  2042.  
  2043.     FUNCTION UPDATEAUTOTRANS: BOOLEAN;
  2044.         { MODIFY RECORD, RETURN TRUE FOR DELETE }
  2045.  
  2046.         BEGIN
  2047.             WITH ATR DO
  2048.                 BEGIN
  2049.                     IF UPDATE>0 THEN        { ADD REQUIRED NUMBER OF DAYS }
  2050.                         ADJUSTDATE(DATE,UPDATE)
  2051.                     ELSE                    { OTHERWISE, ADD MONTHS }
  2052.                         WITH DATE DO
  2053.                             BEGIN
  2054.                                 M:=M-UPDATE;
  2055.                                 WHILE (M>12) DO     { ADJ IF PAST END OF YEAR }
  2056.                                     BEGIN
  2057.                                         INC(Y);
  2058.                                         M:=M-12;
  2059.                                     END;
  2060.                                     { IF 28 OR LATER, SET LAST DAY OF MONTH }
  2061.                                 IF D>=28 THEN
  2062.                                     SETLASTDAY(DATE);
  2063.                             END;
  2064.                     UPDATEAUTOTRANS:=FALSE;
  2065.                     IF COUNT<>0 THEN        { ZERO FOR UNLIMITED }
  2066.                         IF COUNT=1 THEN     { IF LAST ENTRY, FLAG DELETION }
  2067.                             UPDATEAUTOTRANS:=TRUE
  2068.                         ELSE
  2069.                             DEC(COUNT);
  2070.                 END;  { WITH ATR }
  2071.         END;  { UPDATEAUTOTRANS }
  2072.  
  2073.  
  2074.     FUNCTION REQUESTAMOUNT(VAR T: TRANSREC; AC: CHAR): CHAR;
  2075.         { SHOW TRANSACTION, GET AMOUNT.  RETURNS CR IF ENTERED,
  2076.           KEYF3 TO SKIP, KEYF4 TO DELETE, ESC TO POSTPONE. }
  2077.  
  2078.         VAR
  2079.             DT: DATEREC;
  2080.             C:  CHAR;
  2081.             HC: BYTE;
  2082.  
  2083.         BEGIN
  2084.             PUSHHELPCONTEXT(16);
  2085.             SHOWOPTIONS('F3','Skip','','Enter amount',
  2086.                         'F4','Delete','ESC','Postpone');
  2087.             GOTOXY(1,5); TEXTATTR:=TITLECOLOR;
  2088.             WRITEWINDOW(JUSTC(ACSTATUS[AC].NAME,80));
  2089.             TEXTATTR:=MAINCOLOR; GOTOXY(1,8);
  2090.             WORDTODATE(T.DATE,DT);
  2091.             WITH T DO
  2092.                 WRITEWINDOW(JUSTC(DATESTR(DT)+'   '+DETAIL,80));
  2093.             GOTOXY(32,11);
  2094.             REPEAT
  2095.                 C:=EDITINT(APMONEYEDIT,T.AMOUNT,0,MAXMONEY);
  2096.                 IF (T.AMOUNT=0) THEN
  2097.                     REQUESTAMOUNT:=ESC
  2098.                 ELSE
  2099.                     REQUESTAMOUNT:=CR;
  2100.                 IF C=KEYF3 THEN
  2101.                     IF GETYESNO('Skip this entry','Are you sure?') THEN
  2102.                         BEGIN
  2103.                             REQUESTAMOUNT:=KEYF3;
  2104.                             C:=CR;
  2105.                         END;
  2106.                 IF C=KEYF4 THEN
  2107.                     IF GETYESNO('Delete all further entries',
  2108.                                 'Are you sure?') THEN
  2109.                         BEGIN
  2110.                             REQUESTAMOUNT:=KEYF4;
  2111.                             C:=CR;
  2112.                         END;
  2113.             UNTIL (C=CR) OR (C=ESC);
  2114.             POPHELPCONTEXT;
  2115.         END;  { REQUESTAMOUNT }
  2116.  
  2117.  
  2118.     BEGIN  { PROCESSAUTOTRANS }
  2119.         GETTODAY(DT); D:=DATETOWORD(DT);
  2120.         WRITEWINDOW(JUSTC('Processing automatic transactions',80));
  2121.         FOR C:='A' TO 'Z' DO        { CHECK AUTO FILE FOR EACH ACCOUNT }
  2122.             IF ACSTATUS[C].ACTYPE<>UNUSED THEN
  2123.                 BEGIN
  2124.                     {$I-}
  2125.                     ASSIGN(AUTOFILE,DATAFILEPATH+AUTOFN+C+FNEXT);
  2126.                     ASSIGN(TRANSFILE,DATAFILEPATH+TRANSFN+C+FNEXT);
  2127.                     RESET(AUTOFILE); DISKCHECK(IORESULT);
  2128.                     IF FILESIZE(AUTOFILE)<>0 THEN
  2129.                         BEGIN
  2130.                             RESET(TRANSFILE); DISKCHECK(IORESULT);
  2131.                             I:=0;           { GET EACH RECORD IN TURN }
  2132.                             WHILE NOT(EOF(AUTOFILE)) DO     
  2133.                                 BEGIN
  2134.                                     READ(AUTOFILE,ATR); DISKCHECK(IORESULT);
  2135.                                     WHILE (DATETOWORD(ATR.DATE)<=D) DO
  2136.                                         BEGIN   { PREPARE IF DUE FOR ENTRY }
  2137.                                             T.DATE:=DATETOWORD(ATR.DATE);
  2138.                                             T.DETAIL:=ATR.DETAIL;
  2139.                                             T.RECON:=UNREC;
  2140.                                             T.AMOUNT:=ATR.AMOUNT;
  2141.                                             IF T.AMOUNT=0 THEN
  2142.                                                 CC:=REQUESTAMOUNT(T,C)
  2143.                                             ELSE
  2144.                                                 CC:=CR;
  2145.                                             IF ATR.AUTODRCR=DEBIT THEN
  2146.                                                 T.AMOUNT:=-T.AMOUNT;
  2147.                                             IF CC=CR THEN
  2148.                                                 ADDTRANS(ACSTATUS[C],T);
  2149.                                             IF (CC=CR) OR (CC=KEYF3) THEN
  2150.                                                 IF UPDATEAUTOTRANS THEN
  2151.                                                     DELETEAUTOTRANSENTRY(I)
  2152.                                                 ELSE
  2153.                                                     BEGIN
  2154.                                                         SEEK(AUTOFILE,I);
  2155.                                                         DISKCHECK(IORESULT);
  2156.                                                         WRITE(AUTOFILE,ATR);
  2157.                                                         DISKCHECK(IORESULT);
  2158.                                                     END;
  2159.                                             IF CC=KEYF4 THEN
  2160.                                                 DELETEAUTOTRANSENTRY(I);
  2161.                                             { PREVENT LOOP ON POSTPONE/DELETE }
  2162.                                             IF (CC=ESC) OR (CC=KEYF4) THEN
  2163.                                                 WORDTODATE(D+1,ATR.DATE);
  2164.                                         END;
  2165.                                     INC(I);
  2166.                                 END; { WHILE NOT(EOF) }
  2167.                             CLOSE(TRANSFILE); DISKCHECK(IORESULT);
  2168.                         END;
  2169.                     CLOSE(AUTOFILE); DISKCHECK(IORESULT);
  2170.                     {$I+}
  2171.                 END;
  2172.         UPDATEACSTATFILE;
  2173.     END;  { PROCESSAUTOTRANS }
  2174.  
  2175.  
  2176. BEGIN  { MAIN CODE }
  2177.     DATEPARSECURYEAR:=TRUE;
  2178.     DATEPARSEDELIMS:=REMOVE(DATEPARSEDELIMS,'-');
  2179.     DEFINECONSOLEIO;                { SET UP CONSOLE DISPLAY }
  2180.     CRITICALERROROWN(ADDR(CRTCLERRHANDLER));
  2181.     CURSORINSERT:=TRUE;
  2182.     CONFIGFILENAME:=FILESPECDEFAULT(PARAMSTR(1),'.\','HAC','.CFG');
  2183.     DATAFILEPATH:='';
  2184.     ASSIGN(PRN,'LPT1');
  2185.     READCONFIGURATION;              { GET CONFIGURATION DATA }
  2186.     PURGEALLWINDOWS;                { RE-DEFINE CONSOLE FOR NEW COLORS }
  2187.     DEFINECONSOLEIO;
  2188.     {$I-}
  2189.     REWRITE(PRN); DISKCHECK(IORESULT);
  2190.     {$I+}
  2191.     ASSIGN(ACSTATFILE,DATAFILEPATH+ACSTATFN+FNEXT);
  2192.     TEXTATTR:=MAINCOLOR;
  2193.     CLRSCR;
  2194.     GOTOXY(1,2);
  2195.     TEXTATTR:=STATCOLOR;
  2196.     WRITE(DUPLCHAR(#196,80));
  2197.     TEXTATTR:=MAINCOLOR;
  2198.     OPENWINDOW(1);
  2199.     WRITE('HAC Version 1.1');
  2200.     GOTOXY(20,1);
  2201.     WRITEWINDOW(PADL
  2202.         ('Copyright (C) 1992, 1993  Paul Coxwell.  All rights reserved',60));
  2203.     OPENWINDOW(9);
  2204.     TEXTATTR:=HIGHCOLOR; WRITE('F1');
  2205.     TEXTATTR:=MAINCOLOR; WRITE(' Help');
  2206.     OPENWINDOW(7);
  2207.     OPENWINDOW(2);
  2208.     WITH ONLINEHELP DO      { CONFIGURATION FOR ON-LINE HELP SYSTEM }
  2209.         BEGIN
  2210.             WINDOWID:=255;
  2211.             HELPFILENAME:=HELPFN;
  2212.             X1:=10; Y1:=7;
  2213.             X2:=70; Y2:=17;
  2214.             NORMALATTR:=MAINCOLOR;
  2215.             INDEXATTR:=MAINCOLOR; SELECTATTR:=HIGHCOLOR;
  2216.             BORDER:=WBORDER1; BORDERATTR:=HIGHCOLOR;
  2217.             HDRTEXT:='HELP: '; FTRTEXT:='';
  2218.             HDRPOS:=WJUSTLEFT; FTRPOS:=WJUSTRIGHT;
  2219.             HDRATTR:=TITLECOLOR; FTRATTR:=TITLECOLOR;
  2220.             GENERALKEY:=NUL; CONTEXTKEY:=KEYF1; LASTHELPKEY:=NUL;
  2221.             MOVEWINDOWKEY:=HMOVESCROLL;
  2222.             FLAGS:=HFLAGTITLE+HFLAGPAGEIND+HFLAGPAGETEXT;
  2223.         END;
  2224.     HELPERROR:=HELPERRHANDLER;
  2225.     HELPINITIALIZE(ONLINEHELP);
  2226.     HELPCONTEXT:=1;
  2227.     IF ACSTATINIT THEN          { INITIALIZE STATUS FROM FILE OR CREATE NEW }
  2228.         BEGIN
  2229.             PROCESSAUTOTRANS;   { PROCESS OUTSTANDING AUTO TRANSACTIONS }
  2230.             MAINOPT:=NUL;
  2231.             REPEAT              { CALL MAIN MENU/APPROPRIATE ROUTINES }
  2232.                 HELPCONTEXT:=2;
  2233.                 IF NOT(MAINOPT IN ['A'..'Z']) THEN
  2234.                     MAINOPT:=MAINMENU;
  2235.                 HELPCONTEXT:=6;
  2236.                 CASE MAINOPT OF
  2237.                     'A'..'Z':
  2238.                         IF ACSTATUS[MAINOPT].ACTYPE<>UNUSED THEN
  2239.                             CASE ACCESSACCOUNT(MAINOPT) OF
  2240.                                 KEYCPGUP:
  2241.                                     REPEAT
  2242.                                         DEC(MAINOPT);
  2243.                                     UNTIL (ACSTATUS[MAINOPT].ACTYPE<>UNUSED) OR
  2244.                                                 (MAINOPT<'A');
  2245.                                 KEYCPGDN:
  2246.                                     REPEAT
  2247.                                         INC(MAINOPT);
  2248.                                     UNTIL (ACSTATUS[MAINOPT].ACTYPE<>UNUSED) OR
  2249.                                                 (MAINOPT>'Z');
  2250.                                 KEYCHOME:
  2251.                                     BEGIN
  2252.                                         MAINOPT:='A';
  2253.                                         WHILE (MAINOPT<='Z') AND
  2254.                                            (ACSTATUS[MAINOPT].ACTYPE=UNUSED) DO
  2255.                                             INC(MAINOPT);
  2256.                                     END;
  2257.                                 KEYCEND:
  2258.                                     BEGIN
  2259.                                         MAINOPT:='Z';
  2260.                                         WHILE (MAINOPT>='A') AND
  2261.                                            (ACSTATUS[MAINOPT].ACTYPE=UNUSED) DO
  2262.                                             DEC(MAINOPT);
  2263.                                     END;
  2264.                                 ESC:    MAINOPT:=NUL;
  2265.                             END
  2266.                         ELSE
  2267.                             BEGIN
  2268.                                 DISPLAYERROR('Account '+MAINOPT+
  2269.                                             ' not in use at present');
  2270.                                 MAINOPT:=NUL;
  2271.                             END;
  2272.                     KEYF3:
  2273.                         BEGIN
  2274.                             HELPCONTEXT:=3;
  2275.                             ACCOUNTSUMMARY;
  2276.                         END;
  2277.                     KEYF4:
  2278.                         BEGIN
  2279.                             HELPCONTEXT:=4;
  2280.                             ACCOUNTSETUP;
  2281.                         END;
  2282.                 END;  { CASE MAINOPT }
  2283.             UNTIL MAINOPT=KEYF10;
  2284.             {$I-}
  2285.             CLOSE(ACSTATFILE); DISKCHECK(IORESULT);
  2286.             CLOSE(PRN); DISKCHECK(IORESULT);
  2287.             {$I+}
  2288.         END;
  2289.     SELECTWINDOW(0);    { TIDY UP DISPLAY FOR EXIT }
  2290.     CLRSCR;
  2291. END.
  2292.  
  2293.